Given an API like:
class Bar { ... }
class Foo extends Bar { ... }
In Java's Optional
type, we can say:
Optional<Foo> fooOption = ...
fooOption.orElse(aFoo) // returns something of type Foo
But, since Foo
is a Bar
, I would like to be able to say:
Optional<Foo> fooOption = ...
fooOption.orElse(aBar) // returns something of type Bar
As an exercise, I wanted to accomplish this with another type:
public abstract class Option<T> {
// this doesn't compile
public abstract <U super T> U orElse(U other);
}
How would I rewrite this to compile, but also support the ability to widen the type when desired at the same time?
(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller. However, note the @SuppressWarnings annotation: that tells you that this code isn't typesafe. You have to verify it yourself, or you could get ClassCastExceptions at runtime.
The short answer is, that there is no way to find out the runtime type of generic type parameters in Java. A solution to this is to pass the Class of the type parameter into the constructor of the generic type, e.g.
The getReturnType() method of Method class Every Method has a return type whether it is void, int, double, string or any other datatype. The getReturnType() method of Method class returns a Class object that represent the return type, declared in method at time of creating the method.
Type erasure is a process in which compiler replaces a generic parameter with actual class or bridge method. In type erasure, compiler ensures that no extra classes are created and there is no runtime overhead.
But, since
Foo
is aBar
But Bar
is not a Foo
. What I mean is that you can do this:
Optional<Bar> fooOpt = Optional.of(new Foo());
Bar bar = fooOpt.orElse(new Bar());
But you can't do the same thing with Optional<Foo>
because it violates type constraints of Optional.orElse
method.
In hypothetical implementation of Option<T>
you should explicitly define U
as a supertype of T
public class Option<U, T extends U> {
T value;
public U orElse(U other) {
if (value != null) {
return value;
}
return other;
}
}
In that case you could wrote a code like this
Option<Foo, Bar> fooOpt = Option.of(new Foo());
Bar bar = fooOpt.orElse(new Bar());
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