先看下面的一段代码:
public class IntegerTest {
public static void main(String[] args){
Integer a=new Integer(1);
Integer b=new Integer(2);
Integer c=new Integer(3);
Integer d=new Integer(2);
Integer e=127;
Integer f=127;
int i=Integer.valueOf(12);
int m=12;
System.out.println(i==m);
int g=320;
int h=320;
System.out.println(b.equals(d));
System.out.println(c.equals(a+b));
System.out.println(b==d);
System.out.println(e==f);
System.out.println(g==h);
}
}
然后看看结果和自己心中想的是否一样?
true
true
true
false
true
true
现在比较流行的一句话:"my le folen"什么情况?
我们对第四个为false的疑问并不太大.因为我们new了两个对象,内存地址不同,所以当用==比较时,返回无疑问是false.
我们对倒数两个的输出结果疑问比较大.
首先我们看一下Intger的源码.
//IntegerCache代表缓冲池
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() {}
}
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} 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.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们可以从源码里面看出缓冲池的大小为:[-128,127]
所以当两个变量都是Integer类型时,比较的数值在缓冲池以内,输出的结果为true;
Integer a = new Integer(1000);
int b = 1000;
当我们对上面的内容完全了解,我们对这个的结果毫无疑问了.
揭晓答案:true.
有一部分人又好奇,为什么为true,不是缓冲池的大小为[-128,127]嘛.而且在是堆内存中储存.
我们看一下下面的变量的类型,为int类型,当我们比较这两个变量的时候,java会对Integer进行自动拆箱,所以跟缓存没有关系,也就涉及不到范围了.所以输出的结果为true.
但是我们疑问缓冲池的大小是否可以改变?还是一直是[-128,127],其实在jvm给我们提供了一种方法,可以修改缓冲池的大小.
参考链接:https://www.jb51.net/article/129640.htm.里面有详细的解答.
类 | 是否有Cache | 最小值 | 最大值 |
---|---|---|---|
Boolean | 无 | -- | -- |
Byte | ByteCache | -128 | 127(固定) |
Short | ShortCache | -128 | 127(固定) |
Character | CharacterCache | 0 | 127(固定) |
Integer | IntegerCache | -128 | java.lang.Integer.IntegerCache.high |
Long | LongCache | -128 | 127(固定) |
Float | 无 | -- | -- |
Double | 无 | -- | -- |
-Djava.lang.Integer.IntegerCache.high=xxx
通过这个这个可以把缓冲池的参数进行修改.
总结:
使用==的情况:
- 如果比较Integer变量,默认比较的是地址值
- Java的Integer维护了从-128-127的缓存池.
- 如果比较某一边的操作表达式,那么比较的是具体值.
使用equals的情况:
- 无论是Integer还是Long中的equals()默认比较的是数值.
- Long的equals()方法,JDK的默认实现:会判断是否是Long类型.
在通常情况下比较两个数是否相等,尽量不要用==,用equals()放法.
参考文章:
https://mp.weixin.qq.com/s/DmwZc1iv1nWlW1oP5I1UOw
https://blog.csdn.net/jianggujin/article/details/53740267