Java Generics, the type gets lost

Andrey Sh :

The following example, although seemingly correct, won't compile (Eclipse Neon 3, Java 1.8):

class Test {    

    public static class SomeForm<IF extends SomeForm<IF>> {

    }

    public static class BaseFF<IF extends SomeForm<IF>> {

    }

    public static class AuxFF<IF extends SomeForm<IF>>
            extends BaseFF<IF> {

    }

    public interface Interface<IF extends SomeForm<IF>, FF extends BaseFF<IF>> {
        FF getFF1();        
    }

    public static class ZBaseUnit<IF extends SomeForm<IF>, FF extends BaseFF<IF>>
            implements Interface<IF, FF> {

        @Override
        public FF getFF1() {
            return null;
        }

    }

    public static class ZMyUnit<IF extends SomeForm<IF>, FF extends AuxFF<IF>>
            extends ZBaseUnit<IF, FF> {

    }

    public static class ZMyCheck<IF extends SomeForm<IF>, U extends ZMyUnit<IF, ?>> {
        U unit;

        void f() {
            BaseFF<IF> ff1 = unit.getFF1();
        }

    }

}

Eclipse says (on the line inside f() method):

"Type mismatch: cannot convert from capture#2-of ? to Test.BaseFF".

However, if I remove the method getFF1 from the interface Interface (and the @Override annotation in the class ZBaseUnit), it compiles. Is there some logic behind this? Intuitively, it seems that FF passed to Interface is the same as FF passed to ZBaseUnit, so there should be no difference...

Also, there is no error if I add the method in ZMyUnit:

void f() {
    BaseFF<IF> ff1 = getFF1();
}

Any help would be appreciated!

John McClane :

If you add this verification code to you class

public static class GF extends SomeForm<GF> {
}

public static void main(String[] args) {
    ZMyCheck<GF, ZMyUnit<GF, AuxFF<GF>>> z = new ZMyCheck<>();
    z.unit = new ZMyUnit<>();
    z.f();
    System.out.println("OK");
}

and use standard JDK command-line tools (javac and java), then the code will compile and run successfully. The same is true if you use NetBeans (I have no intention to promote NetBeans in any way).

Therefore, the problem is Eclipse-specific. Eclipse has its own built-in compiler and it seems that you've found one of its weaknesses (maybe you need to file a bug report). It is unable to determine that the wildcard ? is, in fact, referring to the type that extends AuxFF<IF> (and, therefore, BaseFF<IF>). You need to indicate this explicitly:

public static class ZMyCheck<IF extends SomeForm<IF>,
    U extends ZMyUnit<IF, ? extends AuxFF<IF>>> {...}

Then all will compile and run swimmingly.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=78748&siteId=1
Recommended