廖雪峰Java4反射与泛型-3范型-6super通配符

java

1.super通配符

1.1super通配符第一种用法

泛型的继承关系

Pair<Integer>不是Pair<Number>的子类,如

static void set(Pair<Integer> p, Integer first, Integer last){...}

set()不接受Pair<Number>

使用<? super Integer>使方法接收所有泛型类型为Integer或Integer超类的Pair类

package com.testArray;

public class PairHepler {

static void set(Pair<? super Integer> p,Integer first,Integer last){

/**

* 对Pair<? super Integer> 调用setFirst()方法:

* 方法签名:void setFirst(? super Integer)

* 可以安全传入Integer类型的变量:p.setFirst(new Integer(123))

*/

p.setFirst(first);

p.setLast(last);

}

static Integer add(Pair<? extends Number> p){

/**

* 对Pair<? super Integer>调用getFirst()方法:

* 方法签名:? super Integer getFirst()

* 无法赋值给Integer类型的变量。因为无法确定返回值就是Integer类型,可以确认其是Integer的超类,但无法确认就是Integer

*/

Number first = p.getFirst();

Number last = p.getLast();

return first.intValue()+last.intValue();

}

}

<? super Integer>的通配符:

* 允许调用set方法传入Integer的引用

* 不允许调用get方法获得Integer的引用

* 唯一例外:可以获取Object引用:Object o = p.getFirst();

void process(List<? super Integer> list){...}

class List<T>{

T.get(int index);//process方法不能调用

void add(T t);//process方法可以调用

void remove(T t);//process方法可以调用

}

1.2super通配符的第二种用法

<T super Integer>的通配符:

限定定义Pair<T>时只能是Integer或Integer的超类

public class Pair<T super Integer>{...}

Pair<Integer> ip = new Pair<>(1, 2);

Pair<Number> np = new Pair<>(1, 2);

Pair<String> sp = new Pair<>("a", "b");//error

2.extends和super的区别

方法参数为<? extends T>和方法参数为<? super T>的区别:

* <? extends T>允许调用方法获取T的引用

* <? super T>允许调用方法传入T的引用

public class Collections{

//把src的每个元素复制到dest中:List<? super T> dest目标,List<? extends T> src源文件

public static <T> void copy(List<? super T> dest, List<? extends T> src){

for(int i=0; i<src.size(); i++){

T t = src.get(i);

dest.add(t);

}

}

}

3.无限定通配符

public class Pair<T> {...}

public class PairHelper{

static boolean isNull(Pair<?> p){

return p.getFirst() == null || p.getLast() == null;

}

}

<?>的通配符:

?号即包括了extends的限制,页包括了super的限制

不允许调用set方法,null除外

只能调用get方法获取Object的引用

因此使用Pair<?>只能获取Object的引用,以及是否为null

Pair<?>和 Pair不同,通常情况下可以引入泛型参数<T>消除<?>通配符

Pair.java

package com.testArray;

public class Pair<T> {

private T first;

private T last;

public Pair(T first,T last){

this.first = first;

this.last = last;

}

public void setFirst(T first){

this.first = first;

}

public T getFirst() {

return first;

}

public void setLast(T last){

this.last = last;

}

public T getLast(){

return last;

}

public String toString(){

return "Pair(" + first+", "+last+")";

}

}

Main.java

package com.testArray;

public class Main {

public static void main(String[] args){

Pair<Integer> p = new Pair<>(0, 0);

System.out.println(p);

set(p, 123, 456);

System.out.println(p);

Pair<Number> n = new Pair<>(1.2,3.4);

System.out.println(n);

set(n,99,88);

System.out.println(n);

}

static void set(Pair<? super Integer> p, Integer first,Integer last){

p.setFirst(first);

p.setLast(last);

//Integer f = p.getFirst();

}

}

4.总结:

使用类似<? super Integer>通配符作为方法参数时表示:

* 方法内部可以调用传入Integer引用的方法:obj.setXXX(Integer n)

* 方法内部无法调用获取Integer引用的方法(Object除外)Integer n = obj.getXxx()

使用类似<T super Integer>定义泛型类时表示:

* 泛型类型限定为Integer或Integer的超类

无限定通配符<?>很少使用,可以用<T>替换

以上是 廖雪峰Java4反射与泛型-3范型-6super通配符 的全部内容, 来源链接: utcz.com/z/393840.html

回到顶部