三种通配符

目录

 

三种通配符

1、子类型限定通配符

2、超类型限定通配符

3、无限定通配符

通配符捕获


三种通配符

Java有三种通配符限定:子类型限定通配符、超类型限定通配符、无类型通配符。

在泛型程序设计语法中,考察了下面的Pair泛型类,也提到了泛型的继承规则。无论S与T是什么关系,Pair<S>和Pair<T>没有任何关系。但当我们有这方面的需求时,就可以使用通配符类型。 

  1. public class Pair<T>{

  2. private T first;

  3. private T second;

  4.  
  5. public T getFirst(){ return first; }

  6. public T getSecond(){ return second; }

  7.  
  8. public void setFirst(T newVal){ first = newVal; }

  9. public void setSecond(T newVal){ second = newVal; }

  10. }

通配符类型中,允许类型参数变化。

1、子类型限定通配符

Pair<? extends Employee>

表示任何Pair泛型类型,它的参数是Employee的子类。比如如果Manager是Employee的子类,那么Pair<Manager>是Pair<? extends Employee>的子类型。

注意:子类型限定通配符可以从泛型类读取,但不能向泛型类写入。用Pair泛型类举例,上面的setFirst()方法和getFirst()方法应该是下面这样:

  1. ? extends Employee getFirst() //子类型限定下的getFirst方法

  2. void setFirst(? extends Employee) //子类型限定下的setFirst方法

因为上溯造型,无论是什么子类型,都可以上溯造型为Employee, 所以我们可以调用getFirst方法进行读取;但setFirst方法不行,编译器只知道需要Employee的一个子类型,但不知道具体类型。它拒绝传递任何特定的类型,毕竟?不能用来匹配。

2、超类型限定通配符

Pair<? super Manager>

这个通配符限制为Manager的所有超类型。带有超类型的通配符可以向泛型对象写入,但不能从泛型对象读取。

  1. void setFirst(? super Manager)

  2. ? super Manager getFirst()

上面不是真正的Java语法,但可以了解编译器知道什么。我们可以调用setManager方法,并传入Manager对象或者它的子类型对象,但不能传入Manager的超类;另外,调用getFirst方法不能保证返回对象的类型。只能把它赋给一个Object。

直观的讲,带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。

3、无限定通配符

Pair<?>

类型Pair<?>的两个方法可以看作:

  1. ? getFirst()

  2. void setFirst(?)

getFirst()的返回值只能赋给一个Object。setFirst()方法不能被调用,甚至不能被Object调用。不过可以调用setFirst(null)。

Pair<?>和Pair本质区别:可以用任意Object对象调用原始类型的setObject方法(涉及到类型擦除问题)。

通配符捕获

例如我们要写一个交换方法,交换的时候必须临时保存第一个元素,但通配符不是类型变量,因此不能像下面这样写:

  1. public static void swap(Pair<?> p){

  2. ? t = p.getFirst(); //Error

  3. p.setFirst(p.getSecond);

  4. p.setSecond(t);

  5. }

上面这种方法不可取,但我们可以通过引入一个辅助方法来实现:

  1. public static <T> void swapHelper(Pair<T> p){

  2. T t = p.getFirst();

  3. p.setFirst(p.getSecond);

  4. p.setSecond(t);

  5. }

注意,swapHelper是一个泛型方法,但swap不是,swap具有固定的Pair<?>类型的参数。现在可以通过swap调用swapHelper:

public static void swap(Pair<?> p){ swapHelper(P); }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值