-1

I am trying to understand internal implementation of object == operator comparison to achieve a same behavior of String == for my user defined class object.

Below is my implementation logic.

1. Bean Class

package com.study.equals;

public class SomeBean {
    int id;
    
    public SomeBean(int id) {
        this.id = id;
    }
    
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof SomeBean) {
            return this.id==((SomeBean)obj).id;
        } else {
            return false;
        }
    }
    
    @Override
    public int hashCode() {
        return this.id + 2000;
    }
    
    @Override
    public String toString() {
        return "[Inside toString: " + this.hashCode() + "]";
    }
}

2. Test Class

package com.study.equals;

public class Test {

public static void main(String[] args) {
    SomeBean obj1 = new SomeBean(10);
    SomeBean obj2 = new SomeBean(10);
    if(obj1 == obj2) {
        System.out.println("true");
    }else {
        System.out.println("false");
    }   
}

}

  • Expected output: true
  • Actual output: false

Doubt

  • Can someone help me to understand why I am getting false here?
  • How can I get true as response here.
  • 1
    You have to use `equals()` when you want to compare objects. – Progman Mar 07 '21 at 15:37
  • FTR: I created an [Ideone demo](https://ideone.com/1hnikI) a while back that highlighted some corner-cases. – Turing85 Mar 07 '21 at 15:39
  • @Progman through equals() I am able to but my question is why can't I achieve it through == like String == does. – Chandan Prakash Sharma Mar 07 '21 at 15:39
  • 1
    == only works for constant String literals in the code, which are handled differently by the compiler (using string pool). With "new String()", == works in the same way as in your example. – dunni Mar 07 '21 at 15:40
  • @dunni gotcha. So can't we achieve constant String literals like behavior in above case? I tried printing obj1 and obj2 directly. Its returning same output as: [Inside toString: 2010]. But still obj1==obj2 returning false. So I am trying to know why it is happening like this? – Chandan Prakash Sharma Mar 07 '21 at 15:48
  • you can do it, but you'll need some way to cache the instances (`List` or `Map`) and implement methods to retrieve cached instances –  Mar 07 '21 at 15:50
  • @ChandanPrakashSharma Please check https://stackoverflow.com/questions/7520432/what-is-the-difference-between-and-equals-in-java for the difference between `==` and `equals()`. – Progman Mar 07 '21 at 15:51
  • You could work around by using some kind of factory method, which has a Map in the background (kind of like the string constant pool), so everytime you ask that factory method for the object with id 10, you would get the same object back. – dunni Mar 07 '21 at 15:51
  • @dunni Found your comment more opt to clarify my understanding on this. Thank you for your suggestion. – Chandan Prakash Sharma Mar 07 '21 at 16:05
  • 1
    just a note `new String("abc") == "abc"` or `new String("abc") == new String("abc")` will also return `false` . . . your code is doing similar –  Mar 07 '21 at 16:05
  • sorry, was composing an answer to show how to do it... but then question got closed ... so rude. Basically add this to the class `private static final Map cache = new HashMap<>();` and the method `public SomeBean intern() { return cache.computeIfAbsent(id, i -> this); }` Test: `SomeBean obj1 = new SomeBean(10).intern();` same for `obj2` –  Mar 07 '21 at 16:19
  • In java you cannot change the behavior of the == operator (or any operator). You can only change the behavior of equals(). By default, equals() uses the == operator, but it is best to override it like String does. – NomadMaker Mar 07 '21 at 16:40

1 Answers1

0

obj1 == obj2 returns true if obj1 and obj2 are referring to exactly the same object. obj1.equals(obj2) can (as in your case) compare the contents of two objects and can return true for two different objects considered equal due to implementation of method equals.

You get the same object (same address in heap memory, same reference) by the statement obj1 = obj2.

If you do this,

obj1 = new ...
obj2 = new ...

these are always two different objects. You force java to make two new objects. These can never be the same according to ==.

Donat
  • 4,157
  • 3
  • 11
  • 26
  • What this statement means for: "exactly the same object"? Does having same hashcode(), object values and same toString() not makes new object qualify for being same? If not, then what makes another object make exactly same? – Chandan Prakash Sharma Mar 07 '21 at 15:51
  • No, the same object means, it has the same location in the Java heap memory. – dunni Mar 07 '21 at 15:52
  • the subtle difference between same (`==`) and equal (`equals`) - first case is just one instance, second distinct instances with equal content (depending on definition) –  Mar 07 '21 at 16:00
  • @Chandan A variable pointing to an object is called a reference: it refers to a certain piece of memory an object takes. If I do `Object b = a`, then I make sure that variable `b` points to the same object as `a`. Then, and only then, `a == b` returns `true`. On the contrary, the `new` operator **always** allocates a new piece of memory, and creates this object. Note that the term `Object` is only a concept in the human mind, the machine only has a sequence of bytes holding data for that particular object. – MC Emperor Mar 07 '21 at 16:40