在Java中使用==而不是equals比较不可变对象是否可以 [英] Is it ok to compare immutable objects in Java using == instead of equals

查看:89
本文介绍了在Java中使用==而不是equals比较不可变对象是否可以的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑两个Integer类型的引用,它们调用静态工厂方法valueOf,如下所示:-

Consider two references of type Integer that call the static factory method valueOf as shown below:-

    Integer a = Integer.valueOf("10"); 
    Integer b = Integer.valueOf("10"); 

考虑到Integer是不可变的,可以使用==而不是equals来比较a和b方法。我猜想valueOf方法可确保仅创建一个值为10的Integer实例,并为每个创建的值为10的Integer返回对该实例的引用。

Considering that Integer is immutable, is it ok to compare a and b using == instead of using equals method. I am guessing that the valueOf method makes sure that only one instance of Integer with the value 10 is created and a reference to this instance is returned for every Integer created with a value 10.

通常,可以比较通过使用==而不是equals调用同一静态工厂方法而创建的不可变类的两个引用吗?

In general, is it ok to compare two references of an immutable class that are created using a call to the same static factory method by using == instead of equals?

编辑:
仅使用Integer类作为示例。我知道,如果使用==比较它们,最多127个整数将返回true。我需要知道的是,当我创建自己的不可变类时,使用方法create()表示MyImmutable,该方法将确保不创建重复的MyImmutable对象,如果我比较使用create方法创建的2个MyImmutable引用,使用==而不是等于。

The Integer class was used just as an example. I am aware thar Intgers upto 127 will return true if they are compared using ==. What i need to know is that when l create my own immutable class, say MyImmutable with a method create() that will ensure that no duplicate MyImmutable objects are created, will it be ok if I compare 2 MyImmutable references created using the create method by using == instead of equals.

推荐答案

不,通常这并不安全。 == 运算符比较引用而不是值。

No, that's not safe in general. The == operator compares the references, not the values.

使用 == 恰好适用于-128到127之间的整数,但不适用于其他整数。下面的代码说明 == 不会总是起作用:

Using == happens to work for integers between -128 and 127, but not for other integers. The following code demonstrates that == won't always work:

Integer a = Integer.valueOf(10); 
Integer b = Integer.valueOf(10); 
System.out.println(a == b);

true

Integer c = Integer.valueOf(1000); 
Integer d = Integer.valueOf(1000); 
System.out.println(c == d);

false

查看其在线运行情况: ideone

See it working online: ideone

对此行为的解释在于 Integer.valueOf

public static Integer valueOf(int i) {
     final int offset = 128;
     if (i >= -128 && i <= 127) { // must cache
         return IntegerCache.cache[i + offset];
     }
     return new Integer(i);
 }

该标准还不要求小输入(-128至127)的装箱整数必须为对象提供相等的引用。

Not also that the standard requires that boxing integers for small inputs (-128 to 127) gives objects with equal references.


5.1.7装箱转换

如果装箱的值p为true,false,一个字节,介于\u0000到\u007f之间的char或int或short数字介于-128和127之间,则令r1和r2为p的任何两次装箱转换的结果。始终是r1 == r2。

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

但是,标准对此范围之外的整数不提供此类保证。

However the standard makes no such guarantees for integers outside this range.


通常,可以比较使用对同一静态工厂方法的调用而创建的不可变类的两个引用,而使用==代替等于?

In general, is it ok to compare two references of an immutable class that are created using a call to the same static factory method by using == instead of equals?

如上所示,它通常无法正常工作。但是,如果确保具有相同值的两个不可变对象始终具有相同的引用,则可以,它可以工作。但是,您必须仔细遵循一些规则:

As shown above, it won't work in general. But if you ensure that two immutable objects with the same value always have the same reference, then yes, it could work. However there are some rules you must follow carefully:


  • 构造函数不得公开。

  • 创建的每个对象

  • 每次要求您创建对象时,都必须首先检查缓存,以查看是否已经创建了具有相同值的对象。
  • li>
  • The constructor must not be public.
  • Every object you create via the static method must be cached.
  • Every time you are asked to create an object you must first check the cache to see if you have already created an object with the same value.

这篇关于在Java中使用==而不是equals比较不可变对象是否可以的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆