The following Java code doesn't compile (using javac 1.8.0_121
)
import java.util.Optional;
class B<T> {}
public class Test {
static B<Integer> f1(B<Object> a) { return null; }
static B<Integer> f2() {
Optional<B> opt = Optional.empty(); // note the raw type B
return opt.map(Test::f1).get();
// error: incompatible types: Object cannot be converted to B<Integer>
}
}
My question is: Why doesn't the code compile as above , and why does it compile if I change f1
to take a raw type:
static B<Integer> f1(B a) { return null; } // program compiles with raw B
My guess is that opt.map
is inferred as returning Optional<Object>
(instead of Optional<B<Integer>>
) but why? I have looked at other issues with generics and type erasure (JLS 4.8), but they all deal with the situation when a method is called on a raw type itself (eg this ). Here, opt
is not raw, it only takes a raw type parameter. Also, why does the second version (where parameter a
is raw B
instead of B<Object>
) work?
Compilation Error Message
Error java: incompatible types: java.lang.Object cannot be converted to B<java.lang.Integer>
Make the f1 use a ? extends Object
? extends Object
, add a wildcard type to B
.
import java.util.Optional;
class B<T> {}
public class Test {
static B<Integer> f1(B<? extends Object> a) { return null; }
static B<Integer> f2() {
Optional<B<?>> opt = Optional.empty(); // note the raw type B
return opt.map(x -> f1(x)).get();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.