Suppose I have an interface
interface Foo<T> {
void foo(T x);
T bar()
}
and an object of this type with unknown parameter: Foo<?> baz
. Then I can call baz.foo(baz.bar())
.
However, now I need to put the value baz.bar()
into a collection and call baz.foo()
on it later on. Something like
List<???> list; // can I tell the compiler this is the same type as baz's wildcard?
list.add(baz.bar());
...
baz.foo(list.get(1));
This doesn't work either:
List<Object> list;
list.add(baz.bar());
...
baz.foo((???) list.get(1)); // I can't write down the type I need to cast to
Is there a way to do this?
EDIT: The above was oversimplified from my actual situation. Say we have
class Bar {
private final Foo<?> foo;
private List<???> list; // the type argument can be selected freely
Bar(Baz baz) {
foo = baz.getFoo(); // returns Foo<?>, can't be changed
}
void putBar() {
list.add(foo.bar());
}
void callFoo() {
foo.foo(list.get(0));
}
}
This is an awkward problem.
The solution is to find a scope which encloses both the uses of the wildcard, put a type variable on it, replace the wildcards with references to the type variable, and then bind the type variable.
In your case, it sounds like the class is the necessary scope. So:
The problem is that you have added a type variable to the class. Now, everywhere that this class is used, any mention of its type needs to have a type bound (so
Whatever<String>
, orWhatever<?>
). That can be incredibly annoying if the code using the class doesn't really care about the type of the things it's keeping in its list.To get around this, you can create a generic holder class. Something like:
But that's pretty ugly. You're introducing a whole new class, and the runtime overhead of a new object, just to work around some annoying generics.