Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

<? extends U> 和 <U> 在元函数中有区别吗?

我知道什么是List<? extends Number>, 但是下面<? extends U>可以写成<U>吗?

Java SE 8 Optional 源码:

public final class Optional<T> {

    private final T value;

    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

可以搜索 泛型的协变和逆变(感谢题主的问题,让我又复习了一下这里…)

不用通配符直接写死的话会造成一些不便,以Optional<String>为例,对于<R> R map(Function<? super T, ? extend R)这个方法:

  1. ? super T写死成T,这里就只能传Function<String, X>不能传Function<Object, X>,即使Function<Object, X>可以用String做参数
  2. ? 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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...