目录
从泛型类派生子类
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类