Search code examples
javagenericscompiler-errorsinstanceoftype-erasure

Method has (unexpectedly) the same erasure as another method


I read all the other questions about this, but i can't understand why there is type erasure in my case. I have

public <T extends Aclass&Binterface> boolean test(final T param) {
    ...
}

public boolean test(final Aclass pOtherPPShape) {
    ...
}

Method test(Aclass) has the same erasure test(Aclass) as another method in type ClassName

How should i write two methods that operate on the same class but one with an interface and one not? (i can't modify the AClass since is from an external library, and have a lot of subtypes with which this code should work)

Is the use of instanceof right in this case?

EDIT: i use this in a collision test. If the shape passed is instance of an interface, i get a collisionmask(with a method of the interface) and then call the "checker", if it's not, i want to instantiate a dummy collisionmask that does some different stuff and pass to the same method of the "checker" (that has as parameters the 2 shapes and 2 collisonmasks)


Solution

  • You've recognized that the issue is about type-erasure, and that you can't "overload" on the one parameter with type-erasure in the way (type-erasure - you will be assimulated). But, you say,

    The generic type signatures are distinct, why did you get a conflict?

    The two types T extends Aclass&Binterface and Aclass are distinct, aren't they?

    Well, yes and no. While in truth they are distinct, under type-erasure they're not distinct**1. An excellent resource explains: "In the process of type erasure the compiler replaces type parameters by their leftmost bound". Which in your case was Aclass, which led to the conflict between the two methods.

    The explanation suggests a ...

    Solution: formalize the combound**2 generic type declaration to establish a unique leftmost bound

    Replace <T extends Aclass&Binterface> with <T extends AandB>, where AandB is created thus:

    1. Define interface Ainterface with Aclass method signatures

    2. Have Aclass implement Ainterface

    3. Define interface AandB extends Ainterface, Binterface.

    OR

    you can use instanceof.


    **1 "Because the longer wave lengths are refracted by the particles in the atmosphere", per Duncan Jones, another excellent resource.

    **2 That'd be compound, cause I couldn't resist the fun :-/