Java范型学习笔记

2017-11-29  本文已影响29人  zhizhuwang

泛型的目的

两种泛型

满足is-a关系的变量都可以作为方法的参数。
但是,A和B之间的关系,以及A的泛型类与B的泛型类之间的关系,是两种不同的关系。
泛型类之间的可以存在继承关系。

类型推断

受限制类型参数

通配符捕获(Wildcard Captrue)

在编译阶段对表达式求值时,编译器可以从代码中推测出一种特定的类型,这种情况被称为通配符捕获。

一般我们不用关注这个过程,除非编译过程中出现通配符捕获相关的错误。

void foo(List<?> i) {
        fooHelper(i);
    }


    // Helper method created so that the wildcard can be captured
    // through type inference.
    private <T> void fooHelper(List<T> l) {
        l.set(0, l.get(2));
    }

public class WildcardErrorBad {

    void swapFirst(List<? extends Number> l1, List<? extends Number> l2) {
      Number temp = l1.get(0);
      l1.set(0, l2.get(0)); // expected a CAP#1 extends Number,
                            // got a CAP#2 extends Number;
                            // same bound, but different types
      l2.set(0, temp);      // expected a CAP#1 extends Number,
                            // got a Number
    }
}

通配符的使用规则

对于通配符的使用来说,一个很让人迷惑的地方在于何时使用extends,何时使用super。总体上看,可以通过把参数分为以下两类来决定使用哪种关键字。

例如,对于Collectionscopy方法:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
dest是出变量,src是入变量。

基于这种分类,可以约定以下使用规则:

简单地说,就是入变量只能读,不能写;出变量只能写,不能读。

特别注意
通过<? extends ...>定义的变量,可以被认为是一种只读的变量。例如: List<? extends ...>的变量只能执行以下几种操作:

扩展思考:

上一篇 下一篇

猜你喜欢

热点阅读