码迷,mamicode.com
首页 > 其他好文 > 详细

泛型(5)-类型通配符的下限

时间:2018-09-16 23:01:18      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:理解   情况   print   支持   元素   功能   wildcards   保存   nbsp   

  除了可以指定通配符的上限之外,Java也允许指定通配符的下限,通配符的下限用<? super 类型>的方式指定,通配符下限的作用于通配符上限的作用恰好相反.

  指定通配符的下限就是为了支持类型型变.比如Foo是Bar的子类,当程序需要一个A<? super Bar>变量时,程序可以将A<Foo>,A<Object>赋值给A<? super Bar>类型的变量,这种方法被称为逆变.

  对于逆变的泛型集合来说,编译器只知道集合元素是下限的父类型,但具体是哪一种父类型则不确定.因此,这种逆变的泛型集合只能向其中添加元素(因为实际赋值的集合元素总是逆变声明的父类),从集合中去元素只能被当成Object类型处理(编译器无法确定取出的到底是哪个父类的对象).

  假设自己实现了一个工具方法:实现将src集合中的元素复制到dest集合的功能,因此dest集合可以保存src集合中的所有元素,所以dest集合元素的类型应该是src集合元素类型的父类.

  对于上面的copy()方法,可以这样理解两个集合参数之间的依赖关系:不管src集合元素的类型是什么,只要dest的集合元素的类型与前者相同或者是前者的父类即可.

package com.j1803.Type_wildcards;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class MyUtils {
   //下面的dest集合元素的类型必须与src集合元素的类型相同,或者是其父类
public static <E> E copy(Collection<? super E>dest,Collection<E>src){
E last=null;
for(E ele:src){
last=ele;
//逆变的泛型集合添加元素是安全的
dest.add(last);
}
return last;
}

public static void main(String[] args) {
List<Shape>list1=new ArrayList<>();
List<Circle>list2=new ArrayList<>();
list2.add(new Circle());
list2.add(new Circle());
Circle circle=MyUtils.copy(list1,list2);
System.out.println(circle);
}

}
answer:
com.j1803.Type_wildcards.Circle@4554617c
上面的方法用到了泛型方法的语法,就是在方法修饰符和返回值类型之间用<>定义泛型形参.

========================================================================================================================
设定泛型形参的上限
  Java泛型不仅允许在使用通配符形参时设定上限,而且可以在定义泛型形参时设定上限,用于表示传给该泛型的形参的实际类型要么是该上限类型,要么就是该上限类型的子类.

package com.j1803.Type_wildcards;
public class AppleDemo <E extends Number>{
private E info;
public AppleDemo(E info) {
this.info = info;
}
public E getInfo() {
return info;
}
public static void main(String[] args) {
AppleDemo<Integer> ai=new AppleDemo<>(23);
//AppleDemo<Integer> ai1=new AppleDemo<>(45.23);//编译错误
AppleDemo<Double> di=new AppleDemo<>(23.23);
//AppleDemo<Double> di1=new AppleDemo<>(45);//编译出错
//AppleDemo<String> s1=new AppleDemo<String>();//编译出错
System.out.println(ai.getInfo());
System.out.println(di.getInfo());
}
}


程序定义了一个AppleDemo泛型类,该AppleDemo类的泛型形参的上限是Number类,这表明使用AppleDemo类时为E形参传入实际类型参数的只能时Number或者Number的子类.
还有一种更极端的情况下,程序需要为为泛型形参设定多个上限(至多有一个父类上限,可以有多个接口上限),表明该泛型形参必须是其父类的子类(是父类本身也行),并且有多个上限接口.如下代码
//表明T类型必须是Number类或其子类,并必须实现java.io.serializable接口
public class AppleDemo<T extends Number & java.io.Seriable>{
......
}


 

泛型(5)-类型通配符的下限

标签:理解   情况   print   支持   元素   功能   wildcards   保存   nbsp   

原文地址:https://www.cnblogs.com/shadow-shine/p/9657796.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!