像这样一段代码:
Integer i=11;
Integer j=11;
System.out.println(i==j);
System.out.println(i.equals(j));
Integer ii=1111;
Integer jj=1111;
System.out.println(ii==jj);
System.out.println(ii.equals(jj));
结果为什么是:
true
true
false
true
我觉得是
false
true
false
true才对呀!
Java对Integer做了什么处理?
Integer i=11;
Integer j=11;
System.out.println(i==j);
System.out.println(i.equals(j));
Integer ii=1111;
Integer jj=1111;
System.out.println(ii==jj);
System.out.println(ii.equals(jj));
结果为什么是:
true
true
false
true
我觉得是
false
true
false
true才对呀!
Java对Integer做了什么处理?
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
这个缓存中
所以在这个范围之间的integer都是一样的,
出了这个范围就不一样了
* The value of the <code>Integer</code>.
*
* @serial
*/
private final int value;/**
* 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);
} /**
* Constructs a newly allocated <code>Integer</code> object that
* represents the specified <code>int</code> value.
*
* @param value the value to be represented by the
* <code>Integer</code> object.
*/
public Integer(int value) {
this.value = value;
}
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
先看最后一行此类在创建大于等于128的数据对象时用的是new的关键字:所以不用解释为为什么 1111==1111是false的原因了
至于-128~127之间的数据用到了下面的源代码
private static class IntegerCache {
private IntegerCache(){} static final Integer cache[] = new Integer[-(-128) + 127 + 1]; static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
看看此类的修饰符就知道它是一个内部类并且它内部实现方式全是静态的当jvm加在此类事就会在缓存区创建好-128到127之间的所有数据对象。至于为甚这样做可想而知:往执行效率反面想
Integer 范围为 -128 到 127
Integer j=11;
System.out.println(i==j);
System.out.println(i.equals(j));
基本数据类型"=="和"equals()"比较的都是数据本身值是否相等。
引用数据类型"=="比较的是引用内存的地址,"equals()"比较的是数值本身,或者是应用对象是否是同一个引用对象。
System.out.println(ii.equals(jj));
至于这个输出的"false"是因为超出了Integer数据类型的范围。Integer的范围是"-127——128"所以这个数就不确定了,所以会是"false"。建议你去看一些内存分析的书,这样就会明白了~
安装jdk的时候会有一个src.zip,里面就是源码
还有那个 == 和 equals
自动装箱
把包装器当基本变量一样使用(Java5的新功能)API开发人员决定:对于所有的包装
器类,如果两个对象具有相同的类型和相同的值,则认为他们是相等的。The API developers decided that for all the wrapper classes, two objects are equal if they are of the same type and have the same value。eg:
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");
输出:
different objects
meaningfully equal
下面代码又会如何呢?Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");
输出:
same object
meaningfully equal
为了节省内存,对于下列包装器对象的两个实例,当他们的基本值相同时,他们总是==:
(1) Boolean
Boolean b1 = true;
Boolean b2 = true;
System.out.println("b1 == b2 : " + (b1 == b2));
Boolean b3 = new Boolean(true);
Boolean b4 = new Boolean(true);
System.out.println("b3 == b4 : " + (b3 == b4));
输出:
b1 == b2 : true
b3 == b4 : false
(2) Byte
(3) Character from \u0000 to \u007f (7f是进制的127)
(4) Short and Integer from -128 to 127
但是需要注意的是:如果是new出来的对象,那么就不相等了,这点跟String类型是相同的,也是属于优化的一种,例如:
Integer i1 = new Integer(1);
Integer i2 = new Integer("1");
System.out.println(i1 == i2);
Integer i3 = new Integer(1);
Integer i4 = new Integer(1);
System.out.println(i3 == i4);
输出:
false
false