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));
}
}
You can wrap your logic in a generic method like this:
public <T> void myMethod(Foo<T> baz) {
List<T> list; // initialise it...
list.add(baz.bar());
// ...
baz.foo(list.get(1));
}
That's the only way I know of, to achieve what you want, without resorting to unsafe casting.
After the OP's edit:
As others have mentioned, the outer class Bar needs to know the common generic type T. Besides, with your constraint of not being able to change the signature of Baz.getFoo(), I guess you'll have to unsafe cast Foo<?> to Foo<T> in the constructor of Bar<T>:
class Bar<T> {
private final Foo<T> foo;
private List<T> list;
Bar(Baz baz) {
// Since baz cannot be changed, you will have to
// unsafe cast Foo<?> to Foo<T> here.
foo = (Foo<T>) baz.getFoo();
}
void putBar() {
list.add(foo.bar());
}
void callFoo() {
foo.foo(list.get(0));
}
}
Alternatively (as Foo, Bar, Baz are not good means of understanding what your real-life use-case does), you can still avoid generifying Bar like this:
class Bar {
private final Foo<Object> foo;
private List<Object> list;
Bar(Baz baz) {
// Since baz cannot be changed, you will have to
// unsafe cast Foo<?> to Foo<Object> here.
foo = (Foo<Object>) baz.getFoo();
}
void putBar() {
list.add(foo.bar());
}
void callFoo() {
foo.foo(list.get(0));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With