Java generic type issue

Steffen Harbich :

Consider the following simplified example:

package com.test;

class B<S> {
    B(Class<S> clazz) {}
}

class A<T> {
    class SubB extends B<SubB> {
        SubB() {
            super(SubB.class);
        }
    }
}

Although IntelliJ is not showing any error (as it usually does when compile errors exist), the actual compilation when starting the program ends with error located in super(SubB.class);:

Error:(8, 23) java: incompatible types: java.lang.Class<com.test.A.SubB> cannot be converted to java.lang.Class<com.test.A<T>.SubB>

I am curious, why is this happening? And how could I solve it?

Compilation is done with AdoptOpenJDK 11.

Johannes Kuhn :

The reason for this behavior is a bit complicated. Consider java.util.List.class, which has the type Class<java.util.List>, not Class<java.util.List<?>>. This is a limitation of the class literal.

In your example, SubB.class has the type Class<com.test.A.SubB>, again with the raw type of SubB. But the constructor expects some type of Class<com.test.A<T>.SubB>.

That's why we need to cast the literal to it's desired type:

super((Class<SubB>) (Class<?>) SubB.class);

This will produce a warning, but a quick examination will show that there is nothing to worry about.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=4308&siteId=1