为什么不在比较原始包装类(如Long,Integer等)时使用==为什么它们不起作用。
public static void main(String[] args) {
Number l = Integer.parseInt("30");
Number l2 = Integer.parseInt("30");
System.out.println(l == l2);
l = Integer.parseInt("3000");
l2 = Integer.parseInt("3000");
System.out.println(l == l2);
}
为什么在上面的代码中一个结果为true而其他为false ???
答案 0 :(得分:2)
首先,警告:你没有比较价值;你正在比较内存地址。
包装类仍然是真正的对象 - 测试对象相等性的唯一方法是使用equals()
方法。如果您正在与兼容的 *原语进行比较,那么自动取消装箱会将Integer
转换为int
,并对其进行相等检查。请注意,Number
无法自动取消装箱;您必须致电intValue()
才能获得int
。
其次,Integer.valueOf()
将cache values in a byte range, from -128 to 127。在该范围内实例化的任何两个Integer
对象将解析为相同的内存地址。
*:其中一个Number
个对象需要成为int
。
答案 1 :(得分:2)
考虑这种情况:
new Integer(30)==new Integer(30)
在==
的每一边都有 new 实例,然后左侧和右侧是不同的对象,并且比较评估为false(因为它测试实例)同一性)。
装箱的情况更复杂,因为它依赖于Integer.valueOf
,它已经缓存了一些低值整数的值(至少在-128到127的范围内,尽管实现可以选择更大的范围)。
此问题类似于以下内容,即使我们被告知我们应该使用true
比较字符串,等式的评估结果为equals
。
String a = "foo";
String b = "foo";
System.out.println(a==b);
答案 2 :(得分:1)
这些行
Number l = Integer.parseInt("30");
Number l2 = Integer.parseInt("30");
由Java编译器(自动发件箱)转换为
Number l = Integer.valueOf(Integer.parseInt("30"));
Number l2 = Integer.valueOf(Integer.parseInt("30"));
Integer.valueOf(int)API表示此方法将始终缓存-128到127(包括)范围内的值。也就是说,返回30个同一个来自缓存的Integer实例;对于3000,返回两个不同的(新)Integer实例。
答案 3 :(得分:1)
根据Java规范java language specification
如果装箱的值p为true,false,字节或\ u0000到\ u007f范围内的char或-128至127(含)之间的整数或短数,则令r1和r2为p的任何两次拳击转换的结果。 r1 == r2总是这样。