Java中(Integer)127 == (Integer)127和(Integer)129 == (Integer)129表达式结果差异分析
2017-04-01 20:22
483 查看
一直觉得自己Java基础还不错,但是第一眼看到(Integer)129 == (Integer)129表达式时竟然无法立刻反映过来结果到底是true还是false,不妨先来看一下下面简单的Java程序:
编译运行后,控制台输出结果如下:
如果平时对Java基础关注比较少,可能有两三年经验的Java程序员也没办法解释为什么会有这种差异,笔者也是在网上查了一些资料才搞清楚来龙去脉。
要弄明白这个问题,首先要熟练掌握Java自动装箱、拆箱相关的知识,Java中的自动装/拆箱发生在运算操作和比较操作时,例如:
使用==进行比较时,情况如下:
如果==两边都是装箱类型,则比较引用是否指向堆内存中的同一个对象。
如过==两边有一边是装箱类型,另外一边是基本类型,则把装箱类型拆箱为基本类型,然后进行比较。例如:
问题就在于,表达式(Integer)127 == (Integer)127和(Integer)129 == (Integer)129的值为什么不同呢?
我们不妨看一下java.lang.Integer类的源码,如下:
这里只截取了一部分关键代码,如上面代码所示,Integer类只对-128~127之间的对象做了缓存,(Integer)127 == (Integer)127两边装箱后,实际指向堆内存中同一个对象,(Integer)129 == (Integer)129,装箱为引用类型后,没有做缓存,指向堆内存中不同对象,所以比较结果为false。
package com.csdn.test; public class Main { public static void main(String[] args) { System.out.println("(Integer)129 == (Integer)129"); System.out.println( (Integer)129 == (Integer)129); System.out.println("(Integer)127 == (Integer)127"); System.out.println((Integer)127 == (Integer)127); } }
编译运行后,控制台输出结果如下:
(Integer)129 == (Integer)129 false (Integer)127 == (Integer)127 true
如果平时对Java基础关注比较少,可能有两三年经验的Java程序员也没办法解释为什么会有这种差异,笔者也是在网上查了一些资料才搞清楚来龙去脉。
要弄明白这个问题,首先要熟练掌握Java自动装箱、拆箱相关的知识,Java中的自动装/拆箱发生在运算操作和比较操作时,例如:
Integer a = 10; a = a + 10; //1.拆箱为int类型 2.计算 a+10 3.把20装箱为Integer类型. System.out.print(a > 10); //1.把a拆箱为int类型 2. 然后比较
使用==进行比较时,情况如下:
如果==两边都是装箱类型,则比较引用是否指向堆内存中的同一个对象。
如过==两边有一边是装箱类型,另外一边是基本类型,则把装箱类型拆箱为基本类型,然后进行比较。例如:
Integer a = new Integer(129); Integer b = new Integer(129); System.out.println(a == b); // 比较引用类型,返回false System.out.println(a == 129); // a进行拆箱,基本类型比较,返回true
问题就在于,表达式(Integer)127 == (Integer)127和(Integer)129 == (Integer)129的值为什么不同呢?
我们不妨看一下java.lang.Integer类的源码,如下:
/* * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang; import java.lang.annotation.Native; /** * The {@code Integer} class wraps a value of the primitive type * {@code int} in an object. An object of type {@code Integer} * contains a single field whose type is {@code int}. * * <p>In addition, this class provides several methods for converting * an {@code int} to a {@code String} and a {@code String} to an * {@code int}, as well as other constants and methods useful when * dealing with an {@code int}. * * <p>Implementation note: The implementations of the "bit twiddling" * methods (such as {@link #highestOneBit(int) highestOneBit} and * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are * based on material from Henry S. Warren, Jr.'s <i>Hacker's * Delight</i>, (Addison Wesley, 2002). * * @author Lee Boynton * @author Arthur van Hoff * @author Josh Bloch * @author Joseph D. Darcy * @since JDK1.0 */ public final class Integer extends Number implements Comparable<Integer> { ... ... private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } ... ... }
这里只截取了一部分关键代码,如上面代码所示,Integer类只对-128~127之间的对象做了缓存,(Integer)127 == (Integer)127两边装箱后,实际指向堆内存中同一个对象,(Integer)129 == (Integer)129,装箱为引用类型后,没有做缓存,指向堆内存中不同对象,所以比较结果为false。
相关文章推荐
- Java中(Integer)127 == (Integer)127和(Integer)129 == (Integer)129表达式结果差异分析
- java读取(正则表达式分析)网页内容
- java用正则表达式分析读取网页内容(2)
- 由Fortify扫描结果而引发的java安全模型分析
- Java IO和Java NIO在文件拷贝上的性能差异分析
- Java IO和Java NIO在文件拷贝上的性能差异分析
- 为一个正则表达式在输出和不输出情况下结果的差异感到十分疑惑!!!
- 深入分析Java使用+和StringBuilder进行字符串拼接的差异
- Java正则表达式获取匹配结果
- java逻辑表达式短路分析
- 深入分析Java使用+和StringBuilder进行字符串拼接的差异
- Java源码分析:Integer中的位运算
- 流行数据库SQL差异分析之“限制结果集行数”
- 用Java模拟通过四则运算表达式字符串,构造逆波兰表达式,计算结果(转载一大牛)
- 由Fortify扫描结果而引发的java安全模型分析
- java用正则表达式分析读取网页内容(1)
- [笔记]流行数据库SQL差异分析之“限制结果集行数”
- Java基础篇笔记(二) ---容易忽视的表达式结果的类型,求概率、几率问题
- Java的正则表达式深入分析
- 深入分析Java使用+和StringBuilder进行字符串拼接的差异