先看源码吧:
public static void main(String args[])
{
/*
* 就和普通的对象一样。i1和i2为引用类型存放在栈区,new Integer(13) 存放在堆区。
*/
Integer i1=new Integer(13);
Integer i2=new Integer(13);
System.out.println(i1==i2);//false
/*
* 这里目前怀疑是对==进行了重载,可以先解释成存在一个拆箱的过程(对i2进行了拆箱操作),进行了 i2和i3的值比较。
*/
int i3=13;
System.out.println(i2==i3);//true
System.out.println(i3==i1);//true
/*
* 范围在-128 到 127之间为true, 反之为false。 这里存在一个自动装箱的过程.猜测是底层处理方式不同。
*/
Integer i4 = 12;
Integer i5 = 12;
System.out.println(i4==i5);//true
i4 = 200;
i5 = 200;
System.out.println(i4==i5);//false
}
注释是我的自己的一些理解,不知道对不对。求达人给个完美的解释。System.out.println(i1==i2);//false 这个很容易理解。
i1和i2指向不同的堆内存地址,结果当时是false。问题①:问题出现了,对下面这个两句有些不理解:
System.out.println(i2==i3);//true
System.out.println(i3==i1);//true
问了下旁边的同事,他的意思是“==”进行了重载,可以先解释成,这里存在一个拆箱的过程(对i2进行了拆箱操作),进行了 i2和i3的值比较。这样理解对吗?
可是我自己的想法是,因为 i3 是基本类型int的变量,所以i3是存放在栈内存中的,13这个数值也是存放在栈内存中的,i3 指向 13。可以这么理解吧,
如果理解是错误的,求达人给画个图解释下,Thanks very much。
如果理解没有错误的话,i3指向的是栈内存中的13这个数值,而引用变量i2指向的堆内存中13这个integer对象,
既然在i2和i3指向的内存地址不同,为什么“System.out.println(i2==i3)” 的结果为 true?这是不是应该先有一个自动拆箱的过程,然后对“==”运算符进行了重载?BTW,假如两个基本类型用“==”进行比较的时候,是比地址呢 还是数值?问题②: /*
* 范围在-128 到 127之间为true, 反之为false。 这里存在一个自动装箱的过程.猜测是底层处理方式不同。
*/
Integer i4 = 12;
Integer i5 = 12;
System.out.println(i4==i5);//true
i4 = 200;
i5 = 200;
System.out.println(i4==i5);//false这里为什么会有一个范围的问题呢?为什么是在-128 到 127之间?底层怎么处理的? 雪地跪求解释!
小弟先谢过各位达人了!
这是因为Integer将-128 到 127之间的数字缓存了,因为他们的使用频率比较高
问别人真的不如自己研究下源代码!
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
static final int high;
static final Integer cache[]; static {
final int low = -128; // high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}
} /**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
这是源码,应该明白了吧
public class Hello{
System.out.println("Hello World");//这是一个例子
}
System.out.println("Hello World");//这是一个例子
}
private static class IntegerCache {
static final int high;
static final Integer cache[]; static {
final int low = -128; // high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}
} /**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}??呵呵
把你的代码放到[code]标签里面,就可以了。
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. During VM initialization the
* getAndRemoveCacheProperties method may be used to get and remove any system
* properites that configure the cache size. At this time, the size of the
* cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
*/第一个问题求解释呀?
System.out.println(i2==i3);//true
System.out.println(i3==i1);//true
问了下旁边的同事,他的意思是“==”进行了重载,可以先解释成,这里存在一个拆箱的过程(对i2进行了拆箱操作),进行了 i2和i3的值比较。这样理解对吗?
可是我自己的想法是,因为 i3 是基本类型int的变量,所以i3是存放在栈内存中的,13这个数值也是存放在栈内存中的,i3 指向 13。可以这么理解吧,
如果理解是错误的,求达人给画个图解释下,Thanks very much。
如果理解没有错误的话,i3指向的是栈内存中的13这个数值,而引用变量i2指向的堆内存中13这个integer对象,
既然在i2和i3指向的内存地址不同,为什么“System.out.println(i2==i3)” 的结果为 true?这是不是应该先有一个自动拆箱的过程,然后对“==”运算符进行了重载?BTW,假如两个基本类型用“==”进行比较的时候,是比地址呢 还是数值?