- 产生背景
- Type类图
- ParameterizedType
- 参数化
- 方法
- Type[] getActualTypeArguments()
- Type getRawType();
- Type getOwnerType();
- GenericArrayType
- 方法
- getGenericComponentType
- TypeVariable
- 方法
- getBounds()
- getGenericDeclaration()
- getName()
- WildcardType
- 方法
泛型信息在运行时将会被擦除,Type的引入使得开发者在程序运行期内获取属性或者类的具体声明成为可能。
Type类图 ParameterizedType英文直译为参数化类型,有的人看到参数化类型就蒙了:和泛型有什么关系?其实参数化类型就是泛型,不要被不同的翻译误导了。
参数化理解参数化类型,先要了解参数化:
假如我有一个边长是4的正方形,计算正方形的面积:4x4 = 16。如果边长变成了3,面积就是3x3 = 9。这时候来了一个聪明人,说我们可以用a代表正方形的边长,所有正方形的边长就是a x a。不管a是多少,只要带入公式就能得到面积。用a代表边长的方式,就称为参数化,具体点可以称为参数化边长。
这时候再来理解参数化类型就方便了,我可以随便定义一个符号代表类型。List中用的是E,Map用的是K和V。所以参数化类型,就是我们经常使用的泛型。
public interface Listextends Collection public interface Map
然后我们看一看C类中,哪个字段的类型是ParameterizedType
public class C {
private List list;
private Map map;
private Class> aClass;
private Bean bean;
private List list_1;
public class Bean {
}
}
结合对参数化的理解,C类中除了list_1,其他字段的类型都是ParameterizedType:
@Test
public void parameterizedTypeInClass(){
Class c = C.class;
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName() + " is ParameterizedType : "+ (field.getGenericType() instanceof ParameterizedType));
}
}
list is ParameterizedType : true map is ParameterizedType : true aClass is ParameterizedType : true bean is ParameterizedType : true list_1 is ParameterizedType : false方法 Type[] getActualTypeArguments()
获取参数的实际类型,说通俗点,就是尖括号<>中的类型
public void getActualTypeArguments(){
Class c = C.class;
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if(field.getGenericType() instanceof ParameterizedType){
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
System.out.println(field.getName() + " : "+ Arrays.toString(genericType.getActualTypeArguments()));
}
}
}
list : [class java.lang.String] map : [class java.lang.String, class java.lang.Integer] aClass : [?] bean : [class java.lang.String]Type getRawType();
返回表示声明此类型的类或接口的Type对象。简单说就是字段基本类型。
@Test
public void getRawType(){
Class c = C.class;
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if(field.getGenericType() instanceof ParameterizedType){
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
System.out.println(field.getName() + " : "+ genericType.getRawType());
}
}
}
list : interface java.util.List map : interface java.util.Map aClass : class java.lang.Class bean : class com.example.myapplication.type.TestParameterizedType$C$BeanType getOwnerType();
Owner的意思是拥有者。如果一个类属于其他了,会返回声明内部类的类,如果不是内部类,则返回null。
@Test
public void getOwnerType(){
Class c = C.class;
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if(field.getGenericType() instanceof ParameterizedType){
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
System.out.println(field.getName() + " : "+ genericType.getOwnerType());
}
}
}
Bean是C类中的内部类,因此Bean的拥有者Owner是C。
list : null map : null aClass : null bean : class com.example.myapplication.type.TestParameterizedType$CGenericArrayType
泛型数组
class A{ T[] arr; } @Test class A { T[] arr; String[] arrString; } @Test public void testGeneric(){ Class aClass = A.class; Field[] declaredFields = aClass.getDeclaredFields(); for (Field declaredField : declaredFields) { Type genericType = declaredField.getGenericType(); System.out.println(declaredField.getName() + " : "+(genericType instanceof GenericArrayType)); } }
arr : true arrString : false方法 getGenericComponentType
返回数组的类型
@Test
public void getGenericComponentType(){
Class aClass = A.class;
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
Type genericType = declaredField.getGenericType();
if (genericType instanceof GenericArrayType) {
System.out.println("getGenericComponentType:"+((GenericArrayType) genericType).getGenericComponentType());
}
}
}
getGenericComponentType:TTypeVariable
类型变量,使用泛型时,常用的大写替代字母,属于这种类型。
//B类声明了2个泛型,即两个TypeVariable public class B{ List list; Map map; E e; public E method(E e){ return e; } } @Test public void TypeVariable() { Class bClass = B.class; Method[] declaredMethods = bClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes(); System.out.println(Arrays.toString(genericParameterTypes)); } System.out.println("--------------------------------------------"); Field[] declaredFields = bClass.getDeclaredFields(); for (Field declaredField : declaredFields) { Type genericType = declaredField.getGenericType(); System.out.println(declaredField.getName() + " : " + (genericType instanceof TypeVariable)); } }
[E] -------------------------------------------- list : false map : false e : true方法 getBounds()
返回表示此类型变量上限的Type对象数组。 请注意,如果没有明确声明上限,则上限为Object。
@Test
public void getBounds(){
TypeVariable>[] typeParameters = B.class.getTypeParameters();
for (TypeVariable> typeParameter : typeParameters) {
System.out.println(typeParameter.getName());
Type[] bounds = typeParameter.getBounds();
System.out.println("bounds:"+Arrays.toString(bounds));
}
}
T bounds:[class java.lang.String] E bounds:[class java.lang.Object]getGenericDeclaration()
返回声明此类型变量的GenericDeclaration对象
关于GenericDeclaration
@Test
public void getGenericDeclaration(){
TypeVariable[] typeParameters = B.class.getTypeParameters();
for (TypeVariable typeParameter : typeParameters) {
System.out.println(typeParameter.getName());
GenericDeclaration genericDeclaration = typeParameter.getGenericDeclaration();
System.out.println(genericDeclaration);
}
}
T class com.example.myapplication.type.TestTypeVariable$B E class com.example.myapplication.type.TestTypeVariable$BgetName()
返回此类型变量的名称
@Test
public void getName(){
TypeVariable[] typeParameters = B.class.getTypeParameters();
for (TypeVariable typeParameter : typeParameters) {
String name = typeParameter.getName();
System.out.println(typeParameter.getName()+" getName:"+name);
}
}
T getName:T E getName:EWildcardType
通配符的类型。例如? , ? extends Number ?和extends Number ,? super Integer 和?
super Integer 。
public class A {
List extends String> ts;//属于WildcardType
List> list;//属于WildcardType
List super Integer> ins;//属于WildcardType
}
@Test
public void wildcardTypeInClass() {
Class aClass = A.class;
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
ParameterizedType genericType = (ParameterizedType) declaredField.getGenericType();
for (Type type1 : genericType.getActualTypeArguments()) {
System.out.println("----------------------------------");
System.out.println("getTypeName(): " + type1.getTypeName());
System.out.println("is WildcardType: "+ (type1 instanceof WildcardType));
}
}
}
getTypeName(): ? extends java.lang.String is WildcardType: true ---------------------------------- getTypeName(): ? is WildcardType: true ---------------------------------- getTypeName(): ? super java.lang.Integer is WildcardType: true方法
WildcardType定义了两个方法
Type[] getUpperBounds();
获取类型的上边界,使用extends关键字时,传递的类型必须是指定类型的子类,指定类型即上边界,使用任何超出上边界的类型都是错误的
Type[] getLowerBounds();
获取类型的下边界,使用super关键字时,传递的类型必须是指定类型的父类,指定类型即下边界,使用任何超出下边界的类型都是错误的
@Test
public void testMethods(){
Class aClass = A.class;
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
ParameterizedType genericType = (ParameterizedType) declaredField.getGenericType();
for (Type type1 : genericType.getActualTypeArguments()) {
System.out.println("getTypeName(): " + type1.getTypeName());
if (type1 instanceof WildcardType) {
System.out.println("getUpperBounds(): " + Arrays.toString(((WildcardType) type1).getUpperBounds()));
System.out.println("getLowerBounds(): " + Arrays.toString(((WildcardType) type1).getLowerBounds()));
System.out.println("----------------------------------");
}
}
}
}
getTypeName(): ? extends java.lang.String getUpperBounds(): [class java.lang.String] getLowerBounds(): [] ---------------------------------- getTypeName(): ? getUpperBounds(): [class java.lang.Obj ect] getLowerBounds(): [] ---------------------------------- getTypeName(): ? super java.lang.Integer getUpperBounds(): [class java.lang.Object] getLowerBounds(): [class java.lang.Integer] ----------------------------------
参考资料:
java Type 详解
Java中rtti的实现–>Type类介绍



