lindsey sawatzky lindsey sawatzky - 3 months ago 7
Java Question

Incompatible Generic Types: Cannot specify sub-type when using .class with generic type

There are many threads relating to Java Generics, and I'm having trouble sorting out why exactly Java doesn't support this (or alternatively, what I need to do to make it work).

public interface Thinger<T> {

Class<? extends Thinger<T>> getThingers();
}

public class Thingy<Qwerty> implements Thinger<String> {

@Override
public Class<? extends Thinger<String>> getThingers() {
return Thingx.class;
}
}

public class Thingx implements Thinger<String> {

@Override
public Class<? extends Thinger<String>> getThingers() {
return Thingy.class; // Incompatible types error
}
}


I can fix the compile error two ways, but both of them end up dropping some kind of typing information that I want to keep!

Option 1



Drop the generic
Qwerty
in
Thingy<Qwerty>
.

public class Thingy implements Thinger<String> {
..
// Ends up fixing the compile error in Thingx


Option 2



Drop the generic
String
in
Class<? extends Thinger<String>>


public class Thingx implements Thinger<String> {

@Override
public Class<? extends Thinger> getThingers() {
return Thingy.class; // Fixed!

Answer

This seems to be a bug with .class when the class is parameterized.

As a workaround, if you have the ability to create an instance of Thingy, use Object#getClass() and then cast the result like this:

return (Class<Thinger<String>>)((Thinger<String>)new Thingy()).getClass();

This produces no compiler or runtime errors when tested:

Class<? extends Thinger<String>> c = new Thingx().getThingers();
System.out.println(c.getGenericInterfaces()[0]);

Output is:

Thinger<java.lang.String>
Comments