Is it possible to compare immutable objects in Java using == instead of equals

Consider two Integer references that invoke the static factory valueOf method, as shown below: -

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

Given that Integer is immutable, is it normal to compare a and b using == instead of using the equals method. I assume that the valueOf method ensures that only one Integer instance is created with a value of 10 and a reference to that instance is returned for every integer created with a value of 10.

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

Edit: The Integer class was used as an example. I know that Intgers before 127 will return true when compared to using ==. I need to know that when I create my own immutable class, say MyImmutable with the create () method, which will ensure that duplicate MyImmutable objects are not created, will it be ok if I compare the 2 MyImmutable links created using the create method using == instead of equals.

+5
source share
5 answers

No, this is not safe at all. The == operator compares links, not values.

Using == works for integers from -128 to 127, but not for other integers. The following code demonstrates that == does not 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 

See how it works on the Internet: ideone

The explanation for this behavior is the implementation of 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); } 

a source

In addition, the standard requires that box integers for small inputs (from -128 to 127) produce objects with equal references.

5.1.7 Boxing Conversion

If the p value in the box is true, false, bytes, and a char in the range from \ u0000 to \ u007f or int or short number between -128 and 127, then let r1 and r2 be the result of any two box conversions on page. It always happens such that r1 == r2.

However, the standard does not provide such guarantees for integers outside this range.


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

As shown above, it does not work at all. But if you guarantee that two immutable objects with the same value always have the same reference, then yes, that might work. However, there are some rules that you must follow:

  • The constructor should not be publicly available.
  • Each object created using the static method must be cached.
  • Each time you are asked to create an object, you must first check the cache to make sure that you have already created the object with the same value.
+6
source

== and equals () are fundamentally different.

You should read this post for more details:

Difference between Equals / equals and ==

This has nothing to do with immutable objects.

+7
source

If your factory method returns the same object for equal input, it is safe to compare them with ==. For example, String.intern works this way. Enumerations can also be compared with ==. But Integer.valueOf returns the same object only for the range -128 ... 127 (in the default configuration).

 Integer.valueOf(127) == Integer.valueOf(127) 

but

 Integer.valueOf(128) != Integer.valueOf(128) 

Generally speaking, you should use the equals method to compare any objects. The == operator can be used to improve performance when there are a small number of different values ​​for an object. I would not recommend using this method if you are 100% not sure what you are doing.

+5
source

Invariability and equality do not necessarily have something to do with each other. == compares for referential equality, which means it compares if both variables point to the same instance of the object. Equality means that both objects have the same meaning. The immutability now means that you cannot change the object after it is built.

So you can have two immutable obejcts that represent the same value (which means they are equal, so a.equals (b) returns true), but this is not the same instance.

I have a small example for you here:

  public class MyPoint {
     private int x;
     private int y;

     public MyPoint (int x, int y) {
         this.x = x;
         this.y = y;
     }

     public int getX () {
         return x;
     }

     public int getY () {
         return y;
     }

     @Override
     public boolean equals (Object obj) {
         if (! (obj instanceof MyPoint))
             return false;
         MyPoint p = (MyPoint) obj;
         return this.x == px && this.y == py;
     }

     / **
      * @param args
      * /
     public static void main (String [] args) {
         MyPoint p = new MyPoint (2, 2);
         MyPoint q = new MyPoint (2, 2);
         MyPoint r = q;

         System.out.println (p == q);
         System.out.println (p == r);
         System.out.println (q == r);
         System.out.println (p.equals (q));
         System.out.println (p.equals (r));
         System.out.println (q.equals (r));

     }

 } 

Exit: false false true true true true

MyPoint is unchanged . You cannot change its values ​​/ its state after it has been initialized. But, as you can see, two myPoint objects may be equal , but they may not be the same.

I think that you mean some kind of fly where there is only one object for each possible state of the object. Flyweight also means that these obejcts are immutable.

+2
source

They are not the same object, so == will not be true. Be safe with objects and use equals() .

+1
source

Source: https://habr.com/ru/post/975951/


All Articles