Reputation: 20710
I'm struggling to capture a wildcard when it is "nested in another wildcard". Is it possible?
The code:
public class ConvolutedGenerics {
// listClass is a class implementing a List of some Serializable type
public void doSomethingWithListOfSerializables(
Class<? extends List<? extends Serializable>> listClass) {
// Capture '? extends Serializable' as 'T extends Serializable'
// The line does not compile with javac 7
captureTheWildcard(listClass); // <------ zonk here
}
// listClass is a class implementing a List of some Serializable type
private <T extends Serializable>
void captureTheWildcard(
Class<? extends List</* ? extends */T>> listClass) {
// Do something
}
}
compiled with javac 7 produces:
ConvolutedGenerics.java:18: error: method captureTheWildcard in class ConvolutedGenerics cannot be applied to given types;
captureTheWildcard(listClass);
^
required: Class<? extends List<T>>
found: Class<CAP#1>
reason: no instance(s) of type variable(s) T exist so that argument type Class<CAP#1> conforms to formal parameter type Class<? extends List<T>>
where T is a type-variable:
T extends Serializable declared in method <T>captureTheWildcard(Class<? extends List<T>>)
where CAP#1 is a fresh type-variable:
CAP#1 extends List<? extends Serializable> from capture of ? extends List<? extends Serializable>
1 error
Besides many more simpler cases I've found
but I could not infer an answer for my problem from those.
Upvotes: 6
Views: 816
Reputation: 122429
It is not possible, as you probably already know.
Let me illustrate with a counter-example:
List<Integer> foo = Arrays.asList(1,2,3);
List<String> bar = Arrays.asList("hi","mom");
List<List<? extends Serializable>> baz = Arrays.asList(foo, bar);
doSomethingWithListOfSerializables(baz);
public void doSomethingWithListOfSerializables(
List<? extends List<? extends Serializable>> listList) {
captureTheWildcard(listList);
}
private <T extends Serializable>
void captureTheWildcard(
List<? extends List<T>> listList) {
// Do something
}
What should T
be?
Upvotes: 4
Reputation: 5147
The problem with your code is that you're trying to call captureTheWildcard
passing different typed parameter then defined here:
private <T extends Serializable> void captureTheWildcard(Class<? extends List<T>> listClass)
You should explicitly say in your method definition that parameter passed is actually of type of Class<? extends List<? extends Serializable>>
or modify the type of listClass
like this:
import java.util.List;
import java.io.Serializable;
public class ConvolutedGenerics {
// listClass is a class implementing a List of some Serializable type
public <T extends Serializable> void doSomethingWithListOfSerializables(
Class<? extends List<T>> listClass) {
// Capture '? extends Serializable' as 'T extends Serializable'
// The line does not compile with javac 7
captureTheWildcard(listClass); // <------ zonk here
}
// listClass is a class implementing a List of some Serializable type
private <T extends Serializable> void captureTheWildcard(Class<? extends List<T>> listClass) {
// Do something
}
}
Compiles well with javac 1.7.0_25
Upvotes: 0