有关==符号
例如下几段代码:
Long l1 = 100l;
Long l2 = 100l;
System.out.println(l1==l2); //结果是true
Long l1 = 1000l;
Long l2 = 1000l;
System.out.println(l1==l2); //结果是false
为什么会出现上面两个不同的结果呢?
首先在上面的赋值过程中java对数据进行了自动装箱,这些变量都是引用类型的,那么使用==符号比较的时候比较的肯定是内存地址,那为什么结果不一样呢?
在Long类中存在一个LongCache缓存类:
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
在LongCache类中有一个静态数组cache[],其值的范围为-128~127。而在上面赋值过程中java对数据自动装箱的过程就像Long中的valueOf方法的过程如下:
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // 范围在-128~127内的时候返回LongCache内的静态数组cache[]
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
所以显然当Long类型变量值在-128~127这个范围内时,返回的是LongCache类中静态数组cache[]中的元素,而静态cache[]数组在类加载的时候已经初始化完毕,所以在-128-127这个范围内的数据,其值相同,返回的对象就都是同一个对象,所以==符号比较其地址,就会返回true,不在这个范围内的则返回false。
有关equals
Long类型也重写了equals方法,下面是源码:
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
先判断传入的obj的类型是否为Long,若是则对obj进行强转,并调用longValue方法,跟进longValue方法中我们能看到:
public long longValue() {
return value;
}
这个value是什么呢,继续跟进:
private final long value;
value就是Long类型的值,即该值本身数据。
所以在equals方法中return value == ((Long)obj).longValue();
该==符号比较的就是这个Long类型变量的数据值本身,而不是地址值。