【问题标题】:Issue in primitive wrapper classes原始包装类中的问题
【发布时间】:2013-03-20 20:45:41
【问题描述】:

在比较 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);
    }

为什么在上面的代码中一个结果为真而另一个为假???

【问题讨论】:

  • Number 是什么类?我可以编写一个任意的“数字”类,并让 == 以任何我想要的方式工作,即使它是荒谬的。
  • @RobertHarvey:Here's the spec for Number。您可以拥有任何类型的 Number 对象,它可以是任何一种数字原始包装器。

标签: java wrapper primitive


【解决方案1】:

考虑这种情况:

 new Integer(30)==new Integer(30) 

== 的每一侧都有一个 new 实例,那么左侧和右侧是不同的对象,比较结果为 false(因为它测试实例身份) .

装箱的情况更复杂,因为它依赖于Integer.valueOf,它已经缓存了一些低值整数的值(至少在 -128 到 127 的范围内,尽管实现可以选择更大的范围)。

此问题类似于以下问题,即使我们被告知应该使用 equals 比较字符串,相等性的计算结果仍为 true

String a = "foo";
String b = "foo";
System.out.println(a==b);

【讨论】:

    【解决方案2】:

    首先,警告:您不是在比较值;您正在比较内存地址。

    包装类仍然是真正的对象 - 测试对象相等性的唯一方法是使用 equals() 方法。如果您要与 compatible* 原语进行比较,那么自动拆箱会将Integer 带入int,并对其进行相等性检查。注意Number 不能自动拆箱;您必须致电 intValue() 才能获得 int 回复。

    其次,Integer.valueOf()cache values in a byte range, from -128 to 127。在该范围内实例化的任何两个Integer 对象都将解析为相同的内存地址。

    *:Number 对象中的任何一个都需要成为 int

    【讨论】:

      【解决方案3】:

      这几行

      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 实例。

      【讨论】:

        【解决方案4】:

        根据java规范java language specification

        如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两次装箱转换的结果。 r1 == r2 总是如此。

        【讨论】:

          猜你喜欢
          • 2021-09-11
          • 2018-06-26
          • 1970-01-01
          • 2013-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-06
          • 2015-02-22
          相关资源
          最近更新 更多