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