Java限制泛型可用类型与泛型通配的方式
在java泛型中,? 表示通配符,代表未知类型,< ? extends Object>表示上边界限定通配符,< ? super Object>表示下边界限定通配符。
通配符 与 T 的区别
T:作用于模板上,用于将数据类型进行参数化,不能用于实例化对象。 ?:在实例化对象的时候,不确定泛型参数的具体类型时,可以使用通配符进行对象定义。 < T > 等同于 < T extends Object> < ? > 等同于 < ? extends Object>
1、限制泛型可用类型概念
(1)在定义泛型类别时,默认在实例化泛型类型的时候可以使用任何类型,但是如果想要限制泛型类型时,只能用某个特定的类型或者是其子类型才能实例化该类型时,可以定义类型时,使用extends关键字指定这个类型必须是继承某个类或实现某个接口(注:此时就不能用implements)
(2)当没有指定泛型继承的类型或接口时,默认使用extends Object,所以默认情况下任何类型都可以做为参数传入。
2、泛型类型通配声明
(1)同一泛型类,如果实例化时给定的实际类型不同时,则这些实例化的类型是不兼容的,不能相互赋值
(2)泛型类实例化之间的不兼容性会带来使用的不便,我们可以使用泛型通配符(?)声明泛型类的变量就可以解决这个问题
示例代码:
class Animal
{
}
class Dog extends Animal
{
}
class Cls<T>
{
T a;
public Cls(T a){
this.a = a;
}
public T getData(){
return a;
}
}
public class Test {
public static void main(String[] args) {
Cls<Integer> cls1 = new Cls<Integer>(10);
System.out.println(cls1.getData());
Cls<String> cls2 = new Cls<String>("张三");
System.out.println(cls2.getData());
Cls<Double> cls3 = new Cls<Double>(8.24);
System.out.println(cls3.getData());
//Cls<Dog> cls4 = new Cls<Dog>(new Dog());
//泛型类型之间不兼容性,不同类型无法转换,我们可以使用泛型通配符(?)来声明泛型类的变量 以解决此问题
// cls4 = cls1;
// cls4 = cls2;
// cls4 = cls3;
Cls<?> cls4; //声明即可
cls4 = cls1;
cls4 = cls2;
cls4 = cls3;
//也可通过extends来限制泛型的上限(?只在、属于Dog或者Animal)
Cls<? extends Dog> cls5;
Cls<Dog> cls6 = new Cls<Dog>(new Dog());
cls5 = cls6;
//用super确定?所属下限
Cls<? super Animal> cls7; //翻译为:?是Animal的父类
//cls7 = cls6; //将Animal改为Dog就行
Cls<? super Dog> cls8;
cls8 = cls6;
}
}
运行结果:
10 张三 8.24

