So we have a generic method like this, which is part of dependency injection initialisation:
public static <TS, TI extends TS> void registerTransient( Class<TS> serviceClass, Class<TI> implementationClass) { // } At some point we found a case where a class might not necessarily be present. And it's an implementation class which we would be injecting multiple off (so the service class is the same as the implementation class.) Naturally you would write this like this:
Class<?> clazz = Class.forName("com.acme.components.MyPersonalImplementation"); registerTransient(clazz, clazz); IDEA has no problems with this, but javac complains:
error: method registerTransient in class TestTrash cannot be applied to given types; required: Class<TS>,Class<TI> found: Class<CAP#1>,Class<CAP#2> reason: inferred type does not conform to declared bound(s) inferred: CAP#2 bound(s): CAP#1 where TS,TI are type-variables: TS extends Object declared in method <TS,TI>registerTransient(Class<TS>,Class<TI>) TI extends TS declared in method <TS,TI>registerTransient(Class<TS>,Class<TI>) where CAP#1,CAP#2 are fresh type-variables: CAP#1 extends Object from capture of ? CAP#2 extends Object from capture of ? What gives? The method requires the second parameter to be a subclass of the first. Irrespective of what class ? happens to be, it's the same class object for both parameters and a class is, I thought, always assignable from itself. It's almost as if javac is unnecessarily inventing a second wildcard type to use for the second parameter and then going "oh dear, you have two wildcards here, so I can't tell if one is assignable from the other."
Class<Foo>instead ofClass<?>. It'll work then.