廖雪峰Java4反射与泛型-3范型-4擦拭法
1.擦拭法是Java泛型的实现方式。
- 编译器把类型
视为Object。
* 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型。换句话说,虚拟机对泛型一无所知,所有的工作都是编译器做的。 - 编译器根据
实现安全的强制转型。
* Java的范型实际是有Java在编译时进行的。编译器内容永远把T视为Object处理,只是在需要转型的时候,根据T的类型实行安全的强制转型。
2.java的泛型是由擦拭法实现的,因此有一些局限:
2.1.不能是基本类型,例如int
- 编译器把T视为Object,Object是无法持有基本类型的
2.2.无法取得带泛型的Class
无论T的类型是什么,返回的永远是范型类。如Pair
public class Main {
public static void main(String[] args){
Pair<String> s = new Pair<>("xiaoming","xiaohong");
Pair<Integer> i = new Pair<>(4,5);
Class c1 = s.getClass();
Class c2 = i.getClass();
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
System.out.print("c1==c2:");
System.out.println(c1==c2);
System.out.print("c1 == Pair.class:");
System.out.println(c1 == Pair.class);
}
}
### 2.3.无法判断带泛型的Class
```#java
//判断instance只能使用Pair
public class Main {
public static void main(String[] args){
Pair2.4.不能实例化T类型,因为擦拭后实际上是new Object()
```#log 实例化T类型必须借助Classpublic class Pair
private T first;
private T last;
public Pair(T first,T last){
this.first = first;
this.last = last;
}
}
IntPair.java
```#java
package com.testArray;
public class IntPair extends Pair<Integer>{
public IntPair(Integer first,Integer last){
super(first,last);
}
}
package com.testArray;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class Main {
public static void main(String[] args){
Pair<String> p = new Pair<>("xiao","ming");
IntPair ip = new IntPair(1,2);
System.out.println(p instanceof Pair);
System.out.println(ip instanceof Pair);
System.out.println(ip instanceof IntPair);
//getSuperClass()获得该类的父类
//getGenericSuperclass()获得带有泛型的父类
//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type type = IntPair.class.getGenericSuperclass();
//ParameterizedType参数化类型,即泛型
ParameterizedType pt = (ParameterizedType) type;
//getActualTypeArguments获取参数化类型的数组,泛型可能有多个
Type[] types = pt.getActualTypeArguments();
Class<?> clazz = (Class<?>) types[0];
/**
* ? 表示不确定的java类型。
* T 表示java类型。
* K V 分别代表java键值中的Key Value。
* E 代表Element。
*/
System.out.println(clazz);
}
}
总结:
* Java的泛型是采用擦拭法实现的
* 擦拭法决定了泛型<T>:
* 不能是基本类型,例如int
* 不能获取带泛型类型的Class,例如Pair<String>.class
* 不能判断带泛型类型的类型,例如: x instanceof Pair<String>
* 不能实例化T类型,例如new T()
* 泛型方法要防止重复定义方法,例如public boolean equals(T obj)
* 子类可以获取父类的泛型类型<T>
https://blog.csdn.net/liang5630/article/details/40185591
https://www.cnblogs.com/skyislimit/p/5665853.html