I'll try to illustrate my problem in the following simplified example:
public class DataHolder<T> {
private final T myValue;
public DataHolder(T value) {
myValue = value;
}
public T get() {
return myValue;
}
// Won't compile
public <R> DataHolder<R super T> firstNotNull(DataHolder<? extends R> other) {
return new DataHolder<R>(myValue != null ? myValue : other.myValue); }
public static <R> DataHolder<R> selectFirstNotNull(DataHolder<? extends R> first,
DataHolder<? extends R> second) {
return new DataHolder<R>(first.myValue != null ? first.myValue : second.myValue);
}
}
Here I want to write generic method firstNotNull
that returns DataHolder
parametrized by common supertype of type parameter T
of the this
and other
argument, so later I could write e.g.
DataHolder<Number> r = new DataHolder<>(3).firstNotNull(new DataHolder<>(2.0));
or
DataHolder<Object> r = new DataHolder<>("foo").firstNotNull(new DataHolder<>(42));
The problem is that this definition of firstNotNull
is rejected by compiler with message that super T
part of type constraint is illegal (syntactically).
However without this constraint definition is also wrong (obviously), because in this case T
and R
are unrelated to each other.
Interestingly, definition of similar static method selectFirstNotNull
is correct and the latter works as expected. Is it possible to achieve the same flexibility with non-static methods in Java type system at all?