原始包装类中的问题

时间:2013-03-30 05:21:59

标签: java wrapper primitive

为什么不在比较原始包装类(如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 ???

4 个答案:

答案 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总是这样。