首先,我锤5月份要开发布会了,在这祝我锤产品大卖。好了,言归正传。最近从上家公司辞职了,在家休息了一小段时间,然后也跑了一些面试,发现多家公司的笔试题中都有Integer和String,然后各种情况下用 ==,或者equals方法去比较,问是否相等。自己发现有些情况下,答题的时候也是连猜带蒙的。刚好最近有时间,人一闲下来呀,还是总得干点什么。所以,就准备好好研究下Integer,String在各种情况下用==,equals去比较,
第一,究竟是在比较什么?
第二,每一步是怎么进行的?
希望这篇文章能够很好的回答上述的两个问题。
我们先来看下Integer类在各种情况下的 ==,equals在比较什么:
代码如下图:
大家可以试着写下自己的判断结果,如果你的结果和运行结果不一致,那你就需要好好看下下面的解析了。如果你的结果和运行结果一致,你也可以看下解析,看你的判断思路是和和下面一致。
System.out.println(i == j); // true
System.out.println(is == js); // false
System.out.println(i == d); // false
System.out.println(i.equals(d)); // true
System.out.println(i == 2); // true
System.out.println(d == 2); // true
System.out.println(2L == g); // true
System.out.println(i.equals(g)); // false
System.out.println(g.equals(2)); // false
众所周知的原则是:
(1) == 比较的是两个对象的内存地址
(2) equals方法没有重写的话是和 == 一样的,比较的是两个对象的地址,如果类重写了equals方法,比较的就是两个对象的内容。(像 Integer,String 等类,都重写了equals方法)
这两条原则大体上是没错的,但是有些情况下,我们用两条原则去判断,有时候有点捉摸不定,有时候出现判断失误了。比如说,Integer i = 2,虚拟机究竟做了什么? is == js 为什么返回false ? 要解释第一个问题,我们需要 用 javap -c -l IntegerTest.class,反编译IntegerTest,拿到字节码,看下虚拟机是怎么执行这段代码的。IntegerTest字节码如下:
public static void main(java.lang.String[]);
Code:
0: iconst_2 // 将 int 型 2 推送至栈顶
// 调用静态方法
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1 // 将栈顶引用型数值存入第二个本地变量
5: iconst_2
6: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
9: astore_2
// 创建一个对象,并将其引用值压入栈顶
10: new #3 // class java/lang/Integer
13: dup // 复制栈顶数值并将复制值压入栈顶
14: iconst_2 // 将 int 型 2 推送至栈顶
// 调用超类构造方法,实例初始化方法,私有方法
15: invokespecial #4 // Method java/lang/Integer."<init>":(I)V
18: astore_3 // 将栈顶引用型数值存入第四个本地变量
19: new #3 // class java/lang/Integer
22: dup
23: sipush 200 // 将一个 短整型(-32768~32767)常量值推送至栈顶
26: invokespecial #4 // Method java/lang/Integer."<init>":(I)V
29: astore 4 // 将栈顶引用型数值存入指定本地变量
31: sipush 200
34: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
37: astore 5
39: sipush 200
42: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
45: astore 6
47: new #5 // class java/lang/Long
50: dup
// 将 long 或 double 型 常量值从常量池中推送至栈顶
51: ldc2_w #6 // long 2l
54: invokespecial #8 // Method java/lang/Long."<init>":(J)V
57: astore 7
59: getstatic #9 // Field java/lang/System.out:Lja