一图看懂Java泛型通配符

clipboard.png

当使用 <? super MyClass> 的时候,代表未知类的继承结构处于 ObjectMyClass 之间,这时html

  • 编译器只能肯定任何返回该未知类型的方法,返回的变量都是 Object 的子类,因此返回的类型就肯定为 Object,好比 getter 方法
  • 使用该未知类型做为参数的方法,该参数必定是 MyClass 的父类,因此能够传递 MyClass 及其子类进去,好比 setter 方法

而使用 <? extends MyClass> 的时候,未知类型必定是 MyClass 的子类,但向下延伸到无穷尽,没法判断java

  • 因此返回未知类型的方法的返回类型有一个上界,就是 MyClass,即返回类型肯定为 MyClass
  • 可是使用未知类型的方法,由于向下继承无限延伸,没法判断下界,因此不能使用该方法,好比 setter(能够 set(null))

使用 <?> 的时候,能够看成 <? extends Object>,即上界是 Object,能够使用 getter 方法,不能够使用 setter 方法。spa

根据上面这些原则,一个简单的例子以下:3d

@Data // lombok,省略了 getter 和 setter
class Holder<T>{
    private T t;

    public <U extends MyClass> void testSetter(Holder<? super MyClass> holder, U u) {
        holder.setT(u); // 能够输入任何 MyClass 及子类的对象
        holder.setT(null);
    }

    public  void testGetter1(Holder<? extends MyClass> holder) {
        MyClass obj = holder.getT(); // 能肯定返回的对象必定是 MyClass 或父类的对象
    }

    public void testGetter2(Holder<?> holder) {
        Object obj = holder.getT(); // 只能肯定返回的对象必定是 Object
    }
}

class MyClass{}

选择限定通配符时的快速判断方法:code

get-put principle:
Use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don't use a wildcard when you do both.

参考:
https://www.ibm.com/developerworks/java/library/j-jtp07018/index.htmlhtm

相关文章
相关标签/搜索