Strange compilation errors for Java generic type parameters and optionals

The following java code cannot be compiled (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 can't the code compile as above? If I change F1 to get the original type, why does it compile

static B<Integer> f1(B a) { return null; } // program compiles with raw B

My guess is opt Map is inferred to return optional < Object > (instead of optional < B < integer > >), but why? I've looked at other issues with generics and type erasure (JLS 4.8), but they both deal with situations when methods are called on the original type itself (such as this) Here, opt is not primitive, it only needs a primitive type parameter In addition, why is the second version (parameter a is original B instead of B < Object >) valid?

Compile error message

Error: incompatible type: Java Lang.Object cannot be converted to B < Java lang.Integer>

Solution

Let F1 use? Extends object to add the 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 content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>