Type接口,反射包的一个接口。Class类实现了此接口。
主要通过两个Demo来展示Type下的几个实现类:ParameterizedType,TypeVariable,GenericArrayType,WildcardType的简单使用:
TypeDemo:ParameterizedType,TypeVariable,GenericArrayType,WildcardType的方法概略
package DemoReflection;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import util.UtilForTest;
public class TypeDemo {
@SuppressWarnings({ "rawtypes", "unused" })
public static void main(String[] args) {
// ParameterizedType
try {
Field f = EntityType.class.getDeclaredField("map");
Type t = f.getGenericType();
UtilForTest.DisplayStr("getClass--:" + t.getClass());
UtilForTest.DisplayStr("getOwnerType--:" + ((ParameterizedType)t).getOwnerType()); // 获得拥有者 Map map 这个 ParameterizedType 的 getOwnerType() 为 null,而 Map.Entryentry 的 getOwnerType() 为 Map 所属于的 Type。
UtilForTest.DisplayStr("getRawType--:" + ((ParameterizedType)t).getRawType()); // 如 Map map 这个 ParameterizedType 返回的是 Map 类的全限定类名的 Type。 getRawType--:interface java.util.Map
UtilForTest.DisplayStr("getActualTypeArguments()[0]--:" + ((ParameterizedType)t).getActualTypeArguments()[0]);// Type[] getActualTypeArguments(); 返回 这个 Type 类型的参数的实际类型数组。 如 Map map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array。
UtilForTest.DisplayStr("getActualTypeArguments()[1]--:" + ((ParameterizedType)t).getActualTypeArguments()[1]);
Field f2 = EntityType.class.getDeclaredField("et");
Type t2 = f2.getGenericType();
UtilForTest.DisplayStr("Type.getClass--:" + t2.getClass());
EntityType2 instance = new EntityType2();
UtilForTest.DisplayStr("EntityType2.getGenericSuperclass.getActualTypeArguments--:" + ((ParameterizedType)instance.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); //getGenericSuperclass获得父类的Type
UtilForTest.ergodicDisplayArray("getDeclaredFields--:", instance.getClass().getDeclaredFields());// 通过EntityType2.getDeclaredField是获得不到EntityType中的map属性的,但是确可以获得私有的属性
UtilForTest.ergodicDisplayArray("getFields--:", instance.getClass().getFields());// 通过EntityType2.getField可以获得父类EntityType中的map属性,无法获得私有的属性
UtilForTest.DisplayStr("getDeclaredField(\"map\").getGenericType()).getActualTypeArguments()[1]--:" + ((ParameterizedType)instance.getClass().getDeclaredField("map2").getGenericType()).getActualTypeArguments()[1]);
Room r = new Room<>();
System.out.println();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
// TypeVariable 和 WildcardType的定义是差不多的 如果是确定的如T则是TypeVariable,如果是不确定?即是一个表达式(包括一个单独的?)则是WildcardType
try {
Field fset2 = EntityType2.class.getDeclaredField("set2");
ParameterizedType pt1 = (ParameterizedType) fset2.getGenericType();
TypeVariable tv1 = (TypeVariable) pt1.getActualTypeArguments()[0];
UtilForTest.ergodicDisplayArray("TypeVariable.getBounds()--:", tv1.getBounds()); //获得上边界的数组
UtilForTest.DisplayStr("getGenericDeclaration()--:" + tv1.getGenericDeclaration()); // 返回的是声明这个 Type 所在的类 的 Type
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
// GenericArrayType 数组
try {
Field farr = EntityType2.class.getDeclaredField("arr");
Type type = farr.getGenericType();
System.out.println("isGenericArrayType--:" + String.valueOf(type instanceof GenericArrayType));
GenericArrayType genericArrayType = (GenericArrayType) type;
System.out.println("genericArrayType.getGenericComponentType()--:" + genericArrayType.getGenericComponentType()); // 获得数组元素
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
// WildcardType 和 TypeVariable的定义是差不多的 如果是确定的如T则是TypeVariable,如果是不确定?即是一个表达式(包括一个单独的?)则是WildcardType
try {
Field fset3 = EntityType2.class.getDeclaredField("set3");
Type type = ((ParameterizedType)fset3.getGenericType()).getActualTypeArguments()[0];
System.out.println("isWildcardType--:" + String.valueOf(type instanceof WildcardType));
WildcardType wildcardType = (WildcardType) type;
System.out.println(wildcardType.getUpperBounds()[0]); // 上界数组
Field fset4 = EntityType2.class.getDeclaredField("set4");
Type type2 = ((ParameterizedType)fset4.getGenericType()).getActualTypeArguments()[0];
System.out.println("isWildcardType--:" + String.valueOf(type2 instanceof WildcardType));
WildcardType wildcardType2 = (WildcardType) type2;
System.out.println(wildcardType2.getUpperBounds()[0]);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
TypeDemo2: ParameterizedType的附加即与Method的交叉使用
package DemoReflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import util.UtilForTest;
public class TypeDemo2 {
public static void main(String[] args) {
// ParameterizedType
try {
Field f = EntityType3.class.getDeclaredField("a");
Type t = f.getGenericType();
UtilForTest.DisplayStr("getClass--:" + t.getClass());
UtilForTest.DisplayStr("getOwnerType--:" + ((ParameterizedType)t).getOwnerType()); // 获得拥有者 Map map 这个 ParameterizedType 的 getOwnerType() 为 null,而 Map.Entry entry 的 getOwnerType() 为 Map 的 Type。
UtilForTest.DisplayStr("getRawType--:" + ((ParameterizedType)t).getRawType()); // 如 Map map 这个 ParameterizedType 返回的是 Map 类的全限定类名的 Type。 getRawType--:interface java.util.Map
UtilForTest.DisplayStr("(Class)getRawType--:" + (Class)(((ParameterizedType)t).getRawType())); // Type是强转为Class是否会报错 不会
UtilForTest.DisplayStr("(Class)getRawType.isAssignableFrom--:" + Collection.class.isAssignableFrom((Class)(((ParameterizedType)t).getRawType()))); // Type强转为Class是否能判断继承关系
try {
List list1 = (ArrayList) ((Class)(((ParameterizedType)t).getRawType())).newInstance(); // Type强转为Class是否能创建实例,这里是因为List是一个接口,所以并不能直接newInstance
UtilForTest.DisplayStr("(List) ((Class)(((ParameterizedType)t).getRawType())).newInstance().size--:" + ((List) ((Class)(((ParameterizedType)t).getRawType())).newInstance()).size()); //
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
UtilForTest.DisplayStr("getActualTypeArguments()[0]--:" + ((ParameterizedType)t).getActualTypeArguments()[0]);// Type[] getActualTypeArguments(); 返回 这个 Type 类型的参数的实际类型数组。 如 Map map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array。
Type t2 = ((ParameterizedType)t).getActualTypeArguments()[0];
UtilForTest.DisplayStr("getActualTypeArguments()[0] instanceof ParameterizedType --:" + String.valueOf(t2 instanceof ParameterizedType)); // ParameterizedType参数的内部参数还为ParameterizedType依然可以正确得出
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
List list = new ArrayList();
listTest(list);
list.getClass().isPrimitive();
}
// 获得方法的参数类型
public static void listTest(List lists){
Type t = lists.getClass();
System.out.println("Start listTest");
UtilForTest.ergodicDisplayArray("List.class.getFields() --:", lists.getClass().getFields()); //
try {
Method m = TypeDemo2.class.getMethod("listTest", List.class);
UtilForTest.DisplayStr("getDeclaringClass --:" + String.valueOf(m.getDeclaringClass())); // 方法定义所在的类
UtilForTest.ergodicDisplayArray("getParameterTypes() --:" , m.getParameterTypes()); // 方法的各个入参的Class数组
UtilForTest.DisplayStr("getDefaultValue --:" + String.valueOf(m.getDefaultValue())); // 默认值,涉及到注解,具体是什么不太清楚
UtilForTest.ergodicDisplayArray("getGenericParameterTypes --:" , m.getGenericParameterTypes()); //方法的各个入参的Type数组
UtilForTest.DisplayStr("getGenericParameterTypes.toString --:" + m.getGenericParameterTypes()[0].toString()); // type to string
UtilForTest.DisplayStr("getGenericParameterTypesIsParameterizedType --:" + String.valueOf(m.getGenericParameterTypes()[0] instanceof ParameterizedType)); // 入参是ParameterizedType-true
UtilForTest.DisplayStr("m.getGenericParameterTypes()[0]. --:" + ((ParameterizedType)m.getGenericParameterTypes()[0]).getActualTypeArguments()[0]); // 见main函数该方法释义
UtilForTest.ergodicDisplayArray("getTypeParameters --:" , m.getTypeParameters()); // TypeVariable 数据 TypeVariable是什么见TypeDemo
UtilForTest.DisplayStr("toGenericString --:" + String.valueOf(m.toGenericString())); // 方法和入参的全限定名
UtilForTest.DisplayStr("toString --:" + String.valueOf(m.toString())); // 入参就不是
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
UtilForTest.DisplayStr("getParameterizedTypeByParamsInstance --:" + String.valueOf(t instanceof ParameterizedType)); // 在方法内部可获得入参Type
}
}
EntityType:
package DemoReflection;
import java.util.Map;
import java.util.Set;
public class EntityType {
public Map map;
public Set set;
public EntityType2 et;
/**
* @return the map
*/
public Map getMap() {
return map;
}
/**
* @param map the map to set
*/
public void setMap(Map map) {
this.map = map;
}
/**
* @return the set
*/
public Set getSet() {
return set;
}
/**
* @param set the set to set
*/
public void setSet(Set set) {
this.set = set;
}
/**
* @return the et
*/
public EntityType2 getEt() {
return et;
}
/**
* @param et the et to set
*/
public void setEt(EntityType2 et) {
this.et = et;
}
public void testMethod(String str){
System.out.println(str);
}
}
EntityType2:
package DemoReflection;
import java.io.Closeable;
import java.io.InputStream;
import java.util.Map;
import java.util.Set;
import javax.management.monitor.StringMonitorMBean;
//public class EntityType2 extends EntityType {
public class EntityType2 extends EntityType {
public Map map2;
public Set set2;
private T[] arr;
public Set extends Number> set3;
public Set> set4;
/**
* @return the map2
*/
public Map getMap2() {
return map2;
}
/**
* @param map2 the map2 to set
*/
public void setMap2(Map map2) {
this.map2 = map2;
}
/**
* @return the arr
*/
public T[] getArr() {
return arr;
}
/**
* @param arr the arr to set
*/
public void setArr(T[] arr) {
this.arr = arr;
}
/**
* @return the set2
*/
public Set getSet2() {
return set2;
}
/**
* @param set2 the set2 to set
*/
public void setSet2(Set set2) {
this.set2 = set2;
}
/**
* @return the set3
*/
public Set extends Number> getSet3() {
return set3;
}
/**
* @param set3 the set3 to set
*/
public void setSet3(Set extends Number> set3) {
this.set3 = set3;
}
/**
* @return the set4
*/
public Set> getSet4() {
return set4;
}
/**
* @param set4 the set4 to set
*/
public void setSet4(Set> set4) {
this.set4 = set4;
}
private void testMethod2(String str){
System.out.println(str);
}
protected void testMethod3(String str){
System.out.println(str);
}
void testMethod4(String str){
System.out.println(str);
}
}
EntityType3:
package DemoReflection;
import java.util.ArrayList;
import java.util.List;
public class EntityType3 {
private List> a = new ArrayList<>();
private Object o;
/**
* @return the a
*/
public List> getA() {
return a;
}
/**
* @param a the a to set
*/
public void setA(List> a) {
this.a = a;
}
/**
* @return the o
*/
public Object getO() {
return o;
}
/**
* @param o the o to set
*/
public void setO(Object o) {
this.o = o;
}
}
package util;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class UtilForTest {
/**
*
* 功能描述:
* 遍历显示数组,末尾会加一个空白行
*
* @param desc 每行数组的统一注释
* @param arr 数组对象
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void ergodicDisplayArray(String desc, T[] arr) {
if (arr.length == 0) {
System.out.println(desc + "数组长度为0");
}
for (int i = 0; i < arr.length; i++) {
System.out.println("Array:--" + desc + arr[i]);
}
System.out.println();
}
/**
*
* 功能描述:
* 显示字符串并加一个空白行
*
* @param str
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void DisplayStr(String str) {
System.out.println("String:--" + str);
System.out.println();
}
/**
*
* 功能描述:
* 遍历显示集合,末尾会加一个空白行
*
* @param desc 每行数组的统一注释
* @param arr 数组对象
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void ergodicDisplayCollection(Collection collection) {
if (collection instanceof List || collection instanceof Set) {
for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
T t = (T) iterator.next();
System.out.println(t);
}
}
System.out.println();
}
/**
*
* 功能描述:
* 遍历显示集合,末尾会加一个空白行
*
* @param desc 每行数组的统一注释
* @param arr 数组对象
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void ergodicDisplayMap(Map map) {
for (Entry e : map.entrySet()) {
System.out.println(e.getKey() + " : " + e.getValue());
}
System.out.println();
}
/**
*
* 功能描述:
* 遍历显示集合,末尾会加一个空白行
*
* @param desc 每行数组的统一注释
* @param arr 数组对象
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void ergodicDisplay(String desc, Object obj) {
System.out.println(desc);
try {
if (obj instanceof Collection>) {
ergodicDisplayCollection((Collection>) obj);
}
if (obj instanceof Map, ?>) {
ergodicDisplayMap((Map, ?>) obj);
}
if (obj.getClass().isArray()) {
ergodicDisplayArray("",(T[]) obj);
}
} catch (Exception e) {
System.out.println(desc + "格式错误,请确定格式");
}
}
}
参考:谈谈Java类型中ParameterizedType,GenericArrayType,TypeVariabl,WildcardType
Type Java类型
提炼Java Reflection
java Type 详解