问题一:比较两个数大小,以下代码结果是什么?为什么会这样。
Integer i1 = new Integer(10000);
Integer i2 = new Integer(10000);
System.out.println(i1 == i2);
System.out.println(i1 <= i2);
- 问题分析:
我们知道比较两个包装类型的数大小,不能使用“==”,因为java中“==”运算符,比较的内存地址是否一致。
这样容易得出:“i1 == i2" 结果为false,那么"i1 <= i2"呢?猜想:i1<i2 肯定是false, i1==i2 false,那应该是false?
接下来我们验证一下猜想是否正确。
- 测试结果:
i1 == i2 (false)
i1 <= i2 (true)
- 分析
为什么i1<i2结果是ture?分析下java字节码 使用命令:javap -c Test.class
Code:
0: new #2 // class java/lang/Integer
3: dup
4: sipush 10000
7: invokespecial #3 // Method java/lang/Integer."<init>":(I)V
10: astore_1
11: new #2 // class java/lang/Integer
14: dup
15: sipush 10000
18: invokespecial #3 // Method java/lang/Integer."<init>":(I)V
21: astore_2
22: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
25: aload_1
26: aload_2
27: if_acmpne 34
30: iconst_1
31: goto 35
34: iconst_0
35: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V
38: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
41: aload_1
42: invokevirtual #6 // Method java/lang/Integer.intValue:()I
45: aload_2
46: invokevirtual #6 // Method java/lang/Integer.intValue:()I
49: if_icmpgt 56
52: iconst_1
53: goto 57
56: iconst_0
57: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V
60: return
第0-10行:new 一个Integer对象,并存到本地变量1中(astore_1:store a reference into local variable 1)
第11-21行:同理,new 一个Integer对象,并存到变量2中(astore_2)
第25行 aload_1: 把本地变量1放入到栈中
第26行 aload_2: 把本地变量2放入到栈中
第27行 if_acmpne : 比较两个变量的引用是否不相等
...
第41-42行 : 把本地变量1的int值放到栈中
第45-46行 : 把本地变量2的int值放到栈中
第49行 if_icmpgt: 比较变量1的值是否大于变量2的值。
由此可知使用的指令if_acmpne 、if_icmpgt不同导致运算结果与猜想不一致。
参考:https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings