可以搜索 泛型的协变和逆变(感谢题主的问题,让我又复习了一下这里…)
不用通配符直接写死的话会造成一些不便,以Optional<String>
为例,对于<R> R map(Function<? super T, ? extend R)
这个方法:
- 把
? super T
写死成T
,这里就只能传Function<String, X>
不能传Function<Object, X>
,即使Function<Object, X>
可以用String
做参数
- 把
? extend R
写死成R
,这里传一个Function<X, String>
,那么就只能用Optaional<String>
来接,不能用Optional<Object>
接,因为类型不匹配
附上一段demo:
import java.util.function.Function;
public class Sf_1010000022734554 {
/**
* 假装自己是一个Optional
*/
private static class Op<T> {
private final T t;
private Op(T t) {
this.t = t;
}
public static <R> Op<R> of(R r) {
return new Op<>(r);
}
/**
* 没有通配符的map1
*/
public <R> Op<R> map1(Function<T, R> function) {
return new Op<>(function.apply(t));
}
/**
* 有通配符的map2
*/
public <R> Op<R> map2(Function<? super T, ? extends R> function) {
return new Op<>(function.apply(t));
}
}
public static void main(String[] args) {
// T = String
Op<String> op = Op.of("x");
Function<Object, String> function1 = Object::toString;
// 这里会报错,因为 Object != String
// Op<R> op1 = op.map1(function1);
// 这里没问题,因为 Object super String
Op<String> op1 = op.map2(function1);
Function<String, String> function2 = s -> s;
// 这里报错,因为 Object != String
// Op<Object> objectOp = op.map1(function2);
// 这里可以,因为 String extends Object
Op<Object> op2 = op.map2(function2);
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…