javagenericscastingequalssuppress-warnings

Equals method with casting of generic parmeterized class


I am using Java 21.

I am trying to write an equals method for MyClass<T>, which defines a nested class MyNested<T> extends Comparable and a getNested() method which returns the instance of the MyNested<T> class which is defined during the construction and an instance of MyClass<T>.

I am unclear how to do this properly.

If I do:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if ((obj == null) || (this.getClass() != obj.getClass())) return false;
        MyClass<?> other = (MyClass<?>) obj;
        return this.getNested().compareTo(other.getNested()) == 0;
    }

I get the compile error: java: incompatible types: MyClass.MyNested<capture#1 of ?> cannot be converted to MyClass.MyNested<T>

This happens because the MyNested.compareTo(...) method wants an object of type MyNested<T>, but other.getNested() returns an object of type MyNested<?>.

If I do:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if ((obj == null) || (this.getClass() != obj.getClass())) return false;
        MyClass<T> other = (MyClass<T>) obj;
        return this.getNested().compareTo(other.getNested()) == 0;
    }

My IDE complains: Unchecked cast: 'java.lang.object' to 'MyClass<T>' which I can make go away by adding @SuppressWarnings("unchecked") on the line before the cast, but I am not certain that this is the correct thing to do since I do not believe that the this.getClass() != obj.getClass() check on the previous line guarantees that the generic types are the same, only that the classes are the same.

What is the correct what to write the equals method in this case?


Solution

  • Just use equals (or the Objects.equals utility method) instead of compareTo, e.g.:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        MyClass<?> other = (MyClass<?>) obj;
        return Objects.equals(getNested(), other.getNested());
    }