代码之家  ›  专栏  ›  技术社区  ›  Uri

比较Java中的字符、整数和相似类型:使用等号还是=?

  •  10
  • Uri  · 技术社区  · 16 年前

    我想确定Java中的一些东西: 如果我有一个字符、一个整数或一个长的字符和这类东西,我应该使用equals还是is==sufficient?

    我知道对于字符串,不能保证每个唯一字符串只有一个实例,但我不确定其他装箱类型。

    我的直觉是使用平等,但我想确保我不会浪费表现。

    9 回复  |  直到 8 年前
        1
  •  30
  •   Jon Skeet    16 年前

    编辑:规范使 一些 装箱转换的保证。从 section 5.1.7 :

    如果装箱的值p为真, 假,一个字节,一个字符在范围内 \ u0000到\u007f,或int或short 数字介于-128和127之间,然后让 R1和R2是任意两个的结果 拳击转换P。它总是 r1==r2的情况。

    实施 可以 用大一点的游泳池,小心点。

    我愿意 真的? 但要避免编写依赖于此的代码。不是因为它可能会失败,而是因为它不明显——很少有人能很好地了解规范。(我以前认为它依赖于实现。)

    你应该使用 equals 或比较基础值,即

    if (foo.equals(bar))
    

    if (foo.intValue() == bar.intValue())
    

    请注意,即使保证自动氧化使用固定值,其他调用方也可以始终创建单独的实例。

        2
  •  7
  •   Joachim Sauer    16 年前

    如果要比较任何对象的值,请使用 .equals() .

    即使(尤其是)如果这些对象是基本包装类型,那么也可以是byte、character、short、integer、long、float、double和boolean。

    == “只有在比较对象的身份时,你才会发现这是非常非常罕见的。事实上,用原始包装纸永远不会得到你想要的。

    只使用 = 在这两种情况之一中:

    1. 参与比较的所有值都是基元类型(最好不是浮点数)
    2. 您真的想知道两个引用是否引用同一个对象(这包括比较 enum s,因为存在绑定到对象标识的值)
        3
  •  4
  •   Brandon Yarbrough    16 年前
    //Quick test
    public class Test {
      public static void main(String[] args) {
        System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
      }
    }
    

    输出:

    “他们平等吗?0“

    答:

    不,他们不平等。必须使用.equals或比较其基元值。

        4
  •  4
  •   TofuBeer    16 年前

    Java Language Spec 5.1.7 :

    如果装箱的值p为真, 假,一个字节,一个字符在范围内 \ u0000到\u007f,或int或short 数字介于-128和127之间,然后让 R1和R2是任意两个的结果 拳击转换P。它总是 r1==r2的情况。

    还有:

    讨论

    理想情况下,拳击一个给定的原始人 值p,将始终产生 相同的参考。实际上,这个 可能无法使用现有的 实施技术。规则 以上是务实的妥协。这个 上述最后条款要求 某些共同的价值观总是被装箱 不可分辨的物体。这个 实现可能会延迟地缓存这些 或急切地。

    对于其他值,此公式 不允许对 上的装箱值的标识 程序员部分。这将允许 (但不需要)分享 所有这些参考文献。

    这确保了 案例中,行为将是 期望的,而不强加不适当的 性能惩罚,特别是在 小型设备。内存有限 例如,实现可能 缓存所有字符和短裤,如 以及 范围为-32K-+32K。

    因此,在某些情况下,==会起作用,而在许多其他情况下,==不会起作用。始终使用.equals是安全的,因为您不能(通常)授予获取实例的方式。

    如果速度是一个因素(大多数等于从一个==比较开始,或者至少他们应该这样做),并且您可以保证它们是如何分配的,并且它们适合上述范围,那么==是安全的。

    有些虚拟机可能会增加该大小,但是假设langauge规范指定的最小大小比依赖特定的虚拟机行为更安全,除非您确实需要这样做。

        5
  •  2
  •   Skip Head    16 年前

    equals(object o)方法的实现几乎总是以

    if(this == o) return true;
    

    所以使用 equals 即使 == 是真的,这并不是什么性能上的冲击。

    我建议总是使用 等于 对象上的方法。

    *当然,有几次你不应该接受这个建议。

        6
  •  1
  •   Varkhan    16 年前

    一般的答案是 ,您不能保证对于相同的数值,您得到的长对象是相同的(即使您限制自己使用long.valueof())。

    但是,有可能通过首先尝试测试引用的相等性(使用==),然后如果失败,则尝试等于()来提高性能。这一切都取决于附加测试和方法调用的比较成本。您的里程可能会有所不同,但值得尝试一个简单的循环测试,看看哪个更好。

        7
  •  1
  •   Peter Lawrey    16 年前

    值得注意的是,如果自动装箱的值可用,那么它们将使用池对象。这就是为什么(整数)0=(整数)0但(整数)128!=(整数)128,用于Java6U13

        8
  •  1
  •   djangofan    8 年前

    我喜欢从视觉上看结果:

      public static void main(String[] args)
      {
            Integer a = 126; //no boxed up conversion, new object ref
            Integer b = 126; //no boxed up conversion, re-use memory address
            System.out.println("Are they equal? " + (a == b)); // true
            Integer a1 = 140; //boxed up conversion, new object
            Integer b1 = 140; //boxed up conversion, new object
            System.out.println("Are they equal? " + (a1 == b1)); // false
            System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
      }
    
        9
  •  0
  •   Steve Kuo    16 年前

    == 比较对象引用 equals(Object obj) 比较对象相等性。 如果存在一个相等对象的多个实例 那么你 必须 使用 equals 用于平等比较。

    实例:

    Integer i1 = new Integer(12345);
    Integer i2 = new Integer(12345);
    

    这些是不同的对象实例,但根据整数的相等性是相等的,因此必须使用 等于(对象obj)

    public enum Gender {
        MALE, FEMALE;
    }
    

    在这种情况下,只有一个 FEMALE 存在所以 = 安全使用。