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

  除了可以指定通配符的上限之外,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>{
......
}


 

转载于:https://www.cnblogs.com/shadow-shine/p/9657796.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
泛型的产生条件 泛型是为了解决在编译期间无法确定类型而引入的,其产生条件包括: 1. 在代码中需要使用到泛型类型,但是这个泛型类型的具体类型在编译期间是不确定的; 2. 在代码中需要对泛型类型进行操作,比如调用其方法或者获取其属性值。 泛型的概念 泛型是指在编写代码时,不需要指定数据类型,而是在使用时再指定具体的数据类型。这样就可以提高代码的复用性和灵活性。 泛型泛型类是指使用泛型定义的类,其中泛型参数可以用在类的成员变量、成员方法、构造方法中。 泛型类派生类 泛型类派生类是指使用泛型定义的类的子类,其中子类可以继续使用父类中定义的泛型类型。 带泛型子类泛型子类是指在继承泛型类时,子类也要使用泛型类型。 不带泛型子类 不带泛型子类是指在继承泛型类时,子类不使用泛型类型泛型接口 泛型接口是指使用泛型定义的接口,其中泛型参数可以用在接口的方法中。 泛型方法 泛型方法是指使用泛型定义的方法,其中泛型参数可以用在方法的参数列表、返回值、方法体中。 类型通配符 类型通配符是指在定义泛型时使用的一种特殊符号,用于表示不确定的类型。 引出类型通配符 类型通配符可以用于引出泛型类型参数的上限或者下限类型通配符的上限 类型通配符的上限是指使用 extends 关键字限制泛型类型参数的范围,表示泛型类型参数必须是某个类型子类或者实现类。 类型通配符下限 类型通配符下限是指使用 super 关键字限制泛型类型参数的范围,表示泛型类型参数必须是某个类型的父类或者超类。 类型擦除 类型擦除是指在编译期间,将泛型类型参数替换为其上限或者 Object 类型的过程。 无限制类型的擦除 无限制类型的擦除是指在泛型类型参数没有明确指定上限或者下限时,将其擦除为 Object 类型。 有限制类型擦除 有限制类型擦除是指在泛型类型参数有明确指定上限或者下限时,将其擦除为上限或者下限。 擦除泛型方法中类型定义的参数 在泛型方法中,如果定义了泛型类型参数,则在编译期间也会进行类型擦除。 桥接方法 在泛型类或者泛型接口中,如果有泛型方法,则在编译期间会自动生成桥接方法来确保类型安全。 泛型数组 泛型数组是指使用泛型定义的数组,其中数组元素的类型泛型类型参数。 泛型与反射 泛型与反射的结合可以实现动态创建泛型类型对象、获取泛型类型信息等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值