I have a generic abstract class Factory<T>
with a method createBoxedInstance()
which returns instances of T
created by implementations of createInstance()
wrapped in the generic container Box<T>
.
abstract class Factory<T> {
abstract T createInstance();
public final Box<T> createBoxedInstance() {
return new Box<T>(createInstance());
}
public final class Box<T> {
public final T content;
public Box(T content) {
this.content = content;
}
}
}
At some points I need a container of type Box<S>
where S
is an ancestor of T
. Is it possible to make createBoxedInstance()
itself generic so that it will return instances of Box<S>
where S
is chosen by the caller? Sadly, defining the function as follows does not work as a type parameter cannot be declared using the super keyword, only used.
public final <S super T> Box<S> createBoxedInstance() {
return new Box<S>(createInstance());
}
The only alternative I see, is to make all places that need an instance of Box<S>
accept Box<? extends S>
which makes the container's content member assignable to S
.
Is there some way around this without re-boxing the instances of T
into containers of type Box<S>
? (I know I could just cast the Box<T>
to a Box<S>
but I would feel very, very guilty.)
Try rewriting your other code to not use Box<S>
but instead uses Box<? extends S>
, so it will accept a Box<T>
, too. This way, you make it explicit that the Box may also contain subclasses of S
.
The following should also work, if you make your Box static
:
public static <S, T extends S> Box<S> createBoxedInstance(Factory<T> factory) {
return new Box<S>(factory.createInstance());
}
However, it may be unable to do type inference for S
, at which point you need:
public static <S, T extends S> Box<S> createBoxedInstance(Factory<T> factory, S dummy) {
return new Box<S>(factory.createInstance());
}
Another variation that is very explict:
public static <S, T extends S> Box<? extends S> createBoxedInstance(Test<T> factory, S dummy) {
return factory.createBoxedInstance(); // Actually a Box<T>
}