结论:
1、无论如何,Integer与new Integer不会相等。
不会经历拆箱过程,因为它们存放内存的位置不一样。
2、两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。
3、两个都是new出来的,则为false。
4、int和integer(new或非new)比较,都为true,因为会把Integer自动拆箱为int,
其实就是相当于两个int类型比较。
Integer a1 = 127;
cmd里javap -v A.class查看.class文件发现调用了Integer.valueOf(127);
jvm指令可参考https://www.cnblogs.com/lsy131479/p/11201241.html
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
VM.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for(int i = 0; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
#private final int value;
public int intValue() {
return value;
}
测试:
Integer a1=1;
Integer a2=2;
Integer a3=3;
Integer a4=3;
Integer a5=321;
Integer a6=321;
Long g=3l;
System.out.println(a3==a4); true
System.out.println(a5==a6); false
System.out.println(a3==(a1+a2)); true
System.out.println(a3.equals(a1+a2)); true
System.out.println(g==(a1+a2)); true
System.out.println(g.equals(a1+a2)); false
前两个判断只调用了if_acmpne,比较栈顶两引用型数值,当结果不相等时跳转。
如第一个的字节码:
45: getstatic #6
#// Field java/lang/System.out:Ljava/io/PrintStream;
48: aload_3
49: aload 4
51: if_acmpne 58
54: iconst_1
55: goto 59
58: iconst_0
59: invokevirtual #7
#// Method java/io/PrintStream.println:(Z)V
把从局部变量表索引3和4的对象引用压入操作数栈的栈顶,
不相同(ne:not equals)就跳转58,压入0(false),否则压入1。再取出打印
a3==(a1+a2)调用了3次Integer.intValue,1次if_icmpne进行int的比较。
a3.equals(a1+a2)调用了2次Integer.intValue和1次Integer.valueOf,
1次Integer.equals
g==(a1+a2)调用了1次Long.longValue,2次Integer.intValue,
和一次lcmp进行int的比较。
g.equals(a1+a2)调用了2次Integer.intValue和1次Integer.valueOf,
1次Long.equals,类型不一返回false
java的Integer的equals和==
最新推荐文章于 2023-06-04 15:24:58 发布