目录
从泛型类派生子类
1.子类不是泛型类,明确父类类型
2.子类和父类都是泛型类
泛型通配符
1.类型通配符上限
2.类型通配符下限
类型擦除
从泛型类派生子类
1.子类不是泛型类,明确父类类型
class DemoA<T>{T name;public T getName() {return name;}public void setName(T name) {this.name = name;}}class DemoAChild extends DemoA<String> {}class TestDemoA {public static void main(String[] args) {DemoAChild dc = new DemoAChild();dc.setName("");//正确传入String类型参数dc.setName(123);//传入Integer编译期间报错}}
2.子类和父类都是泛型类
class DemoA<T>{T name;public T getName() {return name;}public void setName(T name) {this.name = name;}}class DemoAChild<T> extends DemoA<T> {}class TestDemoA {public static void main(String[] args) {DemoAChild<String> dc = new DemoAChild();dc.setName("");//正确传入String类型参数dc.setName(123);//传入Integer编译期间报错}}
泛型通配符
用来指定传入实参类型,用?代替具体的类型实参
1.类型通配符上限
<? exteds T>表示上限为T类型,可传入T及T的子类
package test;public class Fan {public static void main(String[] args) {People2<String> p1=new People2(5);People2<Integer> p2=new People2(6);show(p1);//String不是Number的子类,编译期间报错show(p2);//Integer是Number的子类,编译期间没报错}public static void show(People2<? extends Number> peo){//只能传入Number或Number的子类}}class People2<T>{T age;public People2(T age) {this.age = age;}}
2.类型通配符下限
public class Fan {public static void main(String[] args) {People2<String> p1=new People2(5);People2<Number> p2=new People2(6);show(p1);//String不是Integer的父类,编译期间报错show(p2);//Number是Integer的父类,编译期间没报错}public static void show(People2<? super Integer> peo){//只能传入Integer或Integer的父类}}class People2<T>{T age;public People2(T age) {this.age = age;}}
类型擦除
泛型泛到信息只存在于编译阶段,进入jvm后,与泛型相关的信息会被擦除掉
泛型是jdk1.5之后语法,以前版本不支持,所以底层还是使用Object类型,在编译期间进行类型明确
package test;import java.lang.reflect.Field;public class test {public static void main(String[] args) {Erasure<String> erasure = new Erasure("hello");Field[] fs = erasure.getClass().getDeclaredFields();for (Field f : fs) {System.out.println("Field name " + f.getName() + " type:" + f.getType().getName());}}}class Erasure <T> {T object;public Erasure(T object) {this.object = object;}}
我们通过反射可以看出运行时还是一个Object类