@EqualsAndHashCode on inner class produces invalid cast #362

Closed
lombokissues opened this Issue Jul 14, 2015 · 6 comments

Projects

None yet

2 participants

@lombokissues
Collaborator

Migrated from Google Code (issue 289)

@lombokissues
Collaborator

๐Ÿ‘ค jwnimmer@jaybridge.com ย  ๐Ÿ•— Oct 18, 2011 at 18:30 UTC

What steps will reproduce the problem?
What is the expected output? What do you see instead?

A lombok-generated equals method has problems with instanceof vs type erasure of an outer class.

$ cat Bug.java

public class Bug<T> {
@ lombok.EqualsAndHashCode
public final class Inner {
public int foo;
}
}

$ java -jar lombok.jar delombok -d delombok Bug.java; cat delombok/Bug.java

// Generated by delombok at Tue Oct 18 14:22:08 EDT 2011
public class Bug<T> {
public final class Inner {
public int foo;

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Inner)) return false;
        final Inner other = (Inner)o;
        if (this.foo != other.foo) return false;
        return true;
    }

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + this.foo;
        return result;
    }
}

}

$ javac -classpath lombok.jar delombok/Bug.java

delombok/Bug.java:14: illegal generic type for instanceof
if (!(o instanceof Inner)) return false;
^
1 error

$ java -jar ecj.jar -source 1.6 delombok/Bug.java

  1. ERROR in delombok/Bug.java (at line 14)
    if (!(o instanceof Inner)) return false;
    ^^^^^^^^^^^^^^^^^^^^
    Cannot perform instanceof check against parameterized type Bug<T>.Inner.
    Use the form Bug.Inner instead since further generic type information
    will be erased at runtime

    1 problem (1 error)

What version of the product are you using? On what operating system?

Lombok version: 0.10.1-EDGE 2011-09-20 18:50 UTC
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2)
OpenJDK Server VM (build 19.0-b09, mixed mode)
Ubuntu Lucid (10.04).

Please provide any additional information below.

The fix suggested by ECJ is s/Inner/Bug.Inner/ on instanceof, as in:
if (!(o instanceof Bug.Inner)) return false;
but perhaps using Bug<?>.Inner to be as specific as possible would be best.

@lombokissues
Collaborator

๐Ÿ‘ค jwnimmer@jaybridge.com ย  ๐Ÿ•— Oct 18, 2011 at 18:39 UTC

Two more notes:

  1. Obviously, this only happens with a generically-typed outer class.
  2. When the inner class is non-final, the canEqual method's instanceof
    check encounters the same problem.
@lombokissues
Collaborator

๐Ÿ‘ค pe.fips ย  ๐Ÿ•— Oct 19, 2011 at 21:53 UTC

Good find!

@lombokissues
Collaborator

๐Ÿ‘ค reinierz ย  ๐Ÿ•— Oct 25, 2011 at 13:06 UTC

Very good find. I'd make the case that this is a javac bug, actually, but ecj agrees with javac, so, maybe it's just a boneheaded part of the spec.

Nevertheless, we can fix this by always fully specifying the full chain (Outer.Inner.Innerer.Innermost). Seems easy enough.

@lombokissues
Collaborator

๐Ÿ‘ค reinierz ย  ๐Ÿ•— Oct 25, 2011 at 17:39 UTC

Fixed in 16661be for both eclipse and javac (it was broken in both).

@lombokissues lombokissues removed the accepted label Jul 14, 2015
@lombokissues
Collaborator

End of migration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment