目录
目的:解决类型转换的安全问题,因为object在进行类型转换中,存在隐患。
例在需要时,向下转型,会出现转型异常;java中希望集合存储同一类型的数据,使用泛型,在创建对象的时候,把类型当做参数传递进去,已明确其类型。
1. 概念
泛型:参数化类型(把类型当做参数传进去)
注:没有进行设置类型,默认为Object 类型
//public class CommonResult<T,E> 可以传递多个参数
public class CommonResult<T> {
private int code;
private String message;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public class Test {
public static void main(String[] args) {
CommonResult c = new CommonResult();
c.setData("");//默认为object类型
CommonResult<String> cr = new CommonResult<String>();//把类型作为参数传递进去
cr.setData("c");//String类型
}
}
2. 从泛型派生子类
1. 子类和父类都是泛型类
DemoAChild<String> dc = new DemoAChild();
创建子类对象时传入类型,父类类型与子类类型一致
public class DemoAChild<T> extends DemoA<T>{ }
2. 子类不是泛型类,明确父类类型
如果子类不是泛型类,那么明确父类类型
DemoAChild dc = new DemoAChild();
public class DemoAChild extends DemoA<String>{}
public class Person implements Comparable<Person>{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.id - o.id;// return this.name.compareTo(o.name);
}
Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
因为子类如果不是泛型类,创建子类对象时不能传入类型,父类类型也就无法明确
3. 泛型接口
泛型类与泛型的定义及使用基本相同
子类也是泛型类,子类和父类的泛型类型一致。
子类不是泛型类,父类要明确泛型的数据类型。
Person类实现了一个泛型接口,Person类不是泛型类,所有Comparable接口就需要明确类型
Person类实现了一个泛型接口,Person类不是泛型类,所有Comparable接口就需要明确类型
public class Person implements Comparable<Person>{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.id - o.id;// return this.name.compareTo(o.name);
}
Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
4. 泛型通配符
? 类型通配符(任意的),用来定义表示实际参数的类型
1. 泛型类型的上限<? extends 类型>
只能传入类型以及类型的子类
public class DemoB<T> {
private T date;
public void test(DemoB<? extends Number> db){
}
public static void main(String[] args) {
DemoB<Integer> di = new DemoB<>();
DemoB<Number> dn = new DemoB<>();
di.test(di);
dn.test(dn);
}
}
2. 泛型类型的下限<? super 类型>
只能传入类型以及类型的父类
例:<? super Number> 只能传入Number类型 以及 Number的父类
public class DemoB<T> {
private T date;
public void test(DemoB<? super Number> db){
}
public static void main(String[] args) {
DemoB<Object> di = new DemoB<>();
DemoB<Number> dn = new DemoB<>();
di.test(di);
dn.test(dn);
}
}
5. 类型擦除
泛型是jdk1.5之后的语法,以前的版本还不支持,所以底层还是使用Object作为类型 泛型的主要作用是在编译期间对类型进行明确的, 这个就叫类型擦除
import java.lang.reflect.Field;
import java.util.ArrayList;
public class Demo3 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
ArrayList<String> list = new ArrayList<>();
Class c = list.getClass();
Field f = c.getDeclaredField("elementData");
System.out.println(f.getName()+"::"+f.getType());
}
}