目录
泛型之通配符及类型擦除
通配符
引入泛型以后,在泛型的方法上,如果有n个类型就需要写n个重载,所以引入了通配符
- ? :表示可以接收任意类型
用于方法中,表示可以接收任意类型的泛型类
只能取得类中数据,不能修改数据,因为类型不确定,无法设置确定类型
- ?:extends 类:设置/取得泛型上限
eg:? extends Number:表示泛型必须是Number及其子类
1.用在类上 T extends 类:T必须为类或者类的子类
2.用在方法上 ? extends 类 :只能接收类或者其子类的泛型类
只能取得类中属性,不能修改值(发生父类到子类的向下转型,需要强转,由于具体子类不确定,因此无法转型)
- ? super 类:只能用于方法中,取得泛型下限
eg: ? super String :表示此方法只能取得String以及其父类Object
可以设置属性值(子类到父类是自动向上转型)
class MyClass<T>{
private T value1;
public T getValue1() {
return value1;
}
public void setValue1(T value1) {
this.value1 = value1;
}
}
public class Test{
public static void main(String[] args) {
MyClass<Integer> myClass = new MyClass();
myClass.setValue1(123);
print(myClass);
}
public static void print(MyClass<?> myClass){
System.out.println(myClass.getValue1());
}
}
类型擦除*语法糖*
语法糖:仅存在于源码阶段,编译后就消失不见
定义:
泛型信息仅存在于代码源码阶段,进入JVM之前,与反向相关的信息会被擦除掉。换句话说,泛型类与普通类在Java虚拟机内没有任何区别
泛型类进入JVM之前会进行类型擦除,之前泛型类的类型参数若没有指定上限,会被擦除称为Object类型,如果指定上限,则类型参数被替换为相应类型上限
import java.lang.reflect.Field;
class MyClass<T,E>{
private T message;
private E text;
public E getText(){
return text;
}
public void setText(E text){
this.text = text;
}
public T grtMessage(){
return message;
}
public void setMessage(){
this.message = message;
}
public void testMethod1(T t){
System.out.println(t);
}
}
public class Test{
public static void main(String[] args) {
MyClass<String,Integer>myClass = new MyClass<>();
Class cls = myClass.getClass();
Field[] fields = cls.getDeclaredFields();
for(Field field : fields){
System.out.println(field.getType());
}
}
}