什麼是Type?
Type的類型
Type的用處
ParmeterizedType(參數化類型)的作用
ParameterizedType的主要方法:
Type[] getActualTypeArguments()
返回表示此類型實際類型參數的 Type 對象的數組。
Type getOwnerType()
返回 Type 對象,表示此類型是其成員之一的類型。
Type getRawType()
返回 Type 對象,表示聲明此類型的類或接口。
public class Person {
@Override
public String toString() {
return "Person []";
}
class Animal <T> {
public String name;
}
}
public class TypeBean<T> {
public List<String> list;
private Set<String>[] set;
private List noGerList;
Map.Entry<String,Integer> entry;
Person.Animal<String> animal;
String str = new String();
T t;
}
public class ParameterizedTypeTest{
public static void main(String[] args) throws Exception {
Class<TypeBean> bean = (Class<TypeBean>) Class.forName("TypeBean");
Field[] declaredFields = bean.getDeclaredFields();
int i =1;
for (Field field : declaredFields) {
field.setAccessible(true);
System.out.println("--------------"+i);
System.out.println("field name is : "+field.getName());
System.out.print("field.getGenericType() instanceof ParameterizedType");
System.out.println("--------"+(field.getGenericType() instanceof ParameterizedType));
if(field.getName().equals("animal")){
ParameterizedType type = (ParameterizedType) field.getGenericType();
Type ownerType = type.getOwnerType();
System.out.println("Person.Animal<String>的ownerType是。。。"+ownerType);
Type rawType = type.getRawType();
System.out.println("Person.Animal<String>的rawType是"+rawType);
Type[] actualTypeArguments = type.getActualTypeArguments();
for (Type type2 : actualTypeArguments) {
System.out.println(type2.getTypeName()+"獲取到的actualTypeArguments分別爲:"+type2.getTypeName());
}
System.out.println("Person.Animal<String> instanceof ParameterizedType -----"+(type instanceof ParameterizedType));
}
System.out.println("--------------"+i);
i++;
}
}
}
--------------1
field name is : list
field.getGenericType() instanceof ParameterizedType--------true
--------------1
--------------2
field name is : set
field.getGenericType() instanceof ParameterizedType--------false
--------------2
--------------3
field name is : noGerList
field.getGenericType() instanceof ParameterizedType--------false
--------------3
--------------4
field name is : entry
field.getGenericType() instanceof ParameterizedType--------true
--------------4
--------------5
field name is : animal
field.getGenericType() instanceof ParameterizedType--------true
Person.Animal<String>的ownerType是。。。class Person
Person.Animal<String>的rawType是class Person$Animal
java.lang.String獲取到的actualTypeArguments分別爲:java.lang.String
Person.Animal<String> instanceof ParameterizedType -----true
--------------5
--------------6
field name is : str
field.getGenericType() instanceof ParameterizedType--------false
--------------6
--------------7
field name is : t
field.getGenericType() instanceof ParameterizedType--------false
--------------7
TypeVariable<D>(類型變量)的作用
TypeVariable 是各種類型變量的公共高級接口。類型變量在反射方法首次需要時創建(在此包中指定)。如果類型變量 t 由類型(即類、接口或註釋類型)T 引用,而且 T 由 T 的第 n 個封閉類聲明(請參見 JLS 8.1.2),那麼創建 t 需要解析(請參見 JVMS 5)T 的第 i 個封閉類,其中 i = 0 到 n(包含)。創建某個類型變量決不能導致創建其邊界。重複創建類型變量沒有效果。
可以在運行時將多個對象實例化,以表示一個給定的類型變量。儘管類型變量僅創建一次,這並不意味着任何緩存實例的要求都表示類型變量。不過,表示類型變量的所有實例彼此必須相等 (equal())。因此,使用類型變量的用戶決不能依靠實現此接口的類實例的身份。
這是api中的介紹,其實非常簡單。這就是我們非常常用的聲明類時的泛型。
TypeVariable的主要方法
Type[] getBounds()
返回表示此類型變量上邊界的 Type 對象的數組。如上邊界未顯式聲明,則爲Object。
D getGenericDeclaration()
返回 GenericDeclaration 對象,該對象表示聲明此類型變量的一般聲明。
String getName()
返回此類型變量的名稱,它出現在源代碼中。
public class TypeVariableBean<T> {
public List<String> list;
Class<?> clz;
private Set<String>[] set;
private List noGerList;
Map.Entry<String,Integer> entry;
Person.Animal<String> animal;
String str = new String();
T t;
}
public class Person {
@Override
public String toString() {
return "Person []";
}
class Animal <T> {
public String name;
}
}
TypeVariableTest類public class TypeVariableTest {
public static void main(String[] args) {
Field[] declaredFields = TypeVariableBean.class.getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
Type type = field.getGenericType();
System.out.println("field.getGenericType() instanceof TypeVariable ? ------ "+(type instanceof TypeVariable));
if(field.getGenericType() instanceof TypeVariable){
Type[] bounds = ((TypeVariable) type).getBounds();
int i = 0;
for (Type type2 : bounds) {
System.out.println("------------"+i);
System.out.println("上邊界是:"+type2.getTypeName());
System.out.println("------------"+i);
i++;
}
GenericDeclaration genericDeclaration = ((TypeVariable) type).getGenericDeclaration();
System.out.println("TypeeVariable's Name::::"+((TypeVariable) type).getName());
System.out.println(genericDeclaration);
}
}
}
}
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ true
------------0
上邊界是:java.lang.Object
------------0
TypeeVariable's Name::::T
class TypeVariableBean
我們可以看出,只有最後一個是我們自己在類上定義的泛型時纔是TypeVariable。此時的上邊界是Object,因爲我們沒有顯式的定義其上邊界,現在我們改變一下TypeVariableBean這個類的泛型上邊界。public class TypeVariableBean<T extends Person & Serializable> {
public List<String> list;
Class<?> clz;
private Set<String>[] set;
private List noGerList;
Map.Entry<String,Integer> entry;
Person.Animal<String> animal;
String str = new String();
T t;
}
這時我們運行的結果如下field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ false
field.getGenericType() instanceof TypeVariable ? ------ true
------------0
上邊界是:Person
------------0
------------1
上邊界是:java.io.Serializable
------------1
TypeeVariable's Name::::T
class TypeVariableBean
這時就出現了兩個上邊界。GenericArrayType(泛型數組類型)的作用
GenericArrayType的主要方法:
Type getGenericComponentType()
返回表示此數組的組件類型的 Type 對象。
示例三:public class Person {
@Override
public String toString() {
return "Person []";
}
class Animal <T> {
public String name;
}
}
public interface PersonInterface {
}
public class GenericArrayTypeTest {
public static void main(String[] args) {
Field[] fields = GenericArrayTypeBean.class.getDeclaredFields();
int i =1;
for (Field field : fields) {
Type type = field.getGenericType();
System.out.println("----------"+i);
if(type instanceof ParameterizedType){
System.out.println(type.getTypeName());
System.out.println("field.getGenericType() instanceof ParameterizedType::");
}else if(type instanceof TypeVariable){
System.out.println(type.getTypeName());
System.out.println("field.getGenericType() instanceof TypeVariable::");
}else if(type instanceof GenericArrayType){
System.out.println(type.getTypeName());
System.out.println("field.getGenericType() instanceof GenericArrayType::");
Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
System.out.println(type.getTypeName()+"數組的組成爲:"+genericComponentType.getTypeName());
}else if(type instanceof Class){
System.out.println(type.getTypeName());
System.out.println("field.getGenericType() instanceof Class::");
}else{
System.out.println(type.getTypeName()+" instanceof "+type.getClass());
}
System.out.println("----------"+i);
i++;
}
}
}
----------1
java.util.List<Person>[]
field.getGenericType() instanceof GenericArrayType::
java.util.List<Person>[]數組的組成爲:java.util.List<Person>
----------1
----------2
java.util.Set<K>
field.getGenericType() instanceof ParameterizedType::
----------2
----------3
java.util.Map<K, V>
field.getGenericType() instanceof ParameterizedType::
----------3
----------4
java.util.List<Person>
field.getGenericType() instanceof ParameterizedType::
----------4
----------5
K
field.getGenericType() instanceof TypeVariable::
----------5
----------6
K[]
field.getGenericType() instanceof GenericArrayType::
K[]數組的組成爲:K
----------6
----------7
Person
field.getGenericType() instanceof Class::
----------7
----------8
java.lang.String
field.getGenericType() instanceof Class::
----------8
----------9
PersonInterface
field.getGenericType() instanceof Class::
----------9
由此我們可以看出只要是帶泛型,並且是數組的就屬於GenericArrayType。並且getGenericComponentType方法就是獲得該數組的組成類型。WildcardType(通配符類型)的作用
表示通配符類型參數。
示例如下:
Class<?>
List<? extends Number>
Set<? super T>
WildcardType的主要方法
Type[] getLowerBounds()
返回表示此類型變量下邊界的 Type 對象的數組。
Type[] getUpperBounds()
返回表示此類型變量上邊界的 Type 對象的數組。
public class WildcardTypeBean<K extends Number & Serializable,V> {
List<? extends Person>[] list;
Set<? super Man> set;
K k;
}
public class WildcardTypeTest {
public static void main(String[] args) throws Exception{
Field[] fields = WildcardTypeBean.class.getDeclaredFields();
for (int i = 0; i <fields.length; i++) {
System.out.println("--------------"+(i+1));
Field field = fields[i];
System.out.println("file:"+field);
Type type = field.getGenericType();
if(type instanceof GenericArrayType){
GenericArrayType gat = (GenericArrayType)type;
ParameterizedType genericComponentType = (ParameterizedType)gat.getGenericComponentType();
Type[] actualTypeArguments = genericComponentType.getActualTypeArguments();
WildcardType t = (WildcardType)actualTypeArguments[0];
Type[] upperBounds = t.getUpperBounds();
for (Type type2 : upperBounds) {
System.out.println("upperBounds:"+type2.getTypeName());
}
Type[] lowerBounds = t.getLowerBounds();
for (Type type2 : lowerBounds) {
System.out.println("lowerBounds:"+type2.getTypeName());
}
}else if(type instanceof ParameterizedType){
WildcardType wildcardType = ((WildcardType)((ParameterizedType) type).getActualTypeArguments()[0]);
Type[] lowerBounds = wildcardType.getLowerBounds();
for (Type type2 : lowerBounds) {
System.out.println("lowerBounds:"+type2.getTypeName());
}
}else{
System.out.println(type.getTypeName()+" instanceof "+type.getClass());
}
System.out.println("--------------"+(i+1));
}
}
運行結果:
--------------1
file:java.util.List[] WildcardTypeBean.list
upperBounds:Person
--------------1
--------------2
file:java.util.Set WildcardTypeBean.set
lowerBounds:Man
--------------2
--------------3
file:java.lang.Number WildcardTypeBean.k
K instanceof class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
--------------3