转载https://blog.csdn.net/coslay/article/details/38084343#t8

11.1 泛型反射的经验法则

使用Java的泛型通常分为两种不同的情况:

(1)声明一个可参数化的类/接口。

(2)使用参数化的类。

当写一个类或接口时,可以指定它应该是可参数化的。就像java.util.List接口那样,可以参数化java.util.List来创建一个String列表而不是创建Object列表。

java.util.List在运行时会检查参数化的类型,但是没有办法知道参数化的是什么类型。这是因为在相同的应用程序中类型可以被参数化为所有的类型。但是,当你检查方法或字段所声明使用的参数化类型,你可以在运行时看到可参数化的类型被参数化为什么类型。总之,你不能在运行时看到类型本身被参数化为什么类型,但你可以在使用和参数化它的字段和方法中看到它。

11.2 泛型方法的返回值类型

如果你获取到一个java.lang.reflect.Method 对象,可以获取它的返回值类型信息。下面是一个示例,一个类有一个有参数化返回值类型的方法:

public class MyClass {	protected List<String> stringList = null;	public List<String> getStringList() {		return this.stringList;	}			 }

在这个类中可以获取 getStringList()方法的泛型返回值类型。换句话说,可以探测到getStringList()返回的是List<String> 而不仅是一个 List。如下:

	public static void main(String[] args) throws Exception{		Method method = MyClass.class.getMethod("getStringList", null);				Type returnType = method.getGenericReturnType();		System.out.println("returnType:"+returnType);				if(returnType instanceof ParameterizedType){		       ParameterizedType type = (ParameterizedType) returnType;		       System.out.println("type:"+type);		       		       Type[] typeArguments = type.getActualTypeArguments();		       System.out.println("typeArguments:"+typeArguments+",size:"+typeArguments.length);		     		       for(Type typeArgument : typeArguments){		           Class typeArgClass = (Class) typeArgument;		           System.out.println("typeArgClass = " + typeArgClass);		       }	}

 }

输出:

returnType:java.util.List<java.lang.String>type:java.util.List<java.lang.String>typeArguments:[Ljava.lang.reflect.Type;@287b2e39,size:1typeArgClass = class java.lang.String

Type[]数组 typeArguments包含一项 -一个代表类java.lang.String Class实例 。 Class实现了 Type接口。

11.3 泛型方法的参数类型

通过Java反射可以在运行时访问参数类型的泛型类型。下面的示例中,类有一个使用参数化的List作为参数的方法:

public class MyClass {
     protected List<String> stringList = null;


 
public void setStringList(List<String> list){
        this.stringList = list;
     }
}

可以访问方法参数的泛型参数类型,如下:

public static void main(String[] args) throws Exception{
Method method = MyClass.class.getMethod("setStringList", List.class);

Type[] genericParameterTypes = method.getGenericParameterTypes();
System.out.println("genericParameterTypes:"+genericParameterTypes);

for(Type genericParameterType : genericParameterTypes){

       if(genericParameterType instanceof ParameterizedType){

          ParameterizedType aType = (ParameterizedType) genericParameterType;
          System.out.println("aType:"+aType);
          
          Type[] parameterArgTypes = aType.getActualTypeArguments();

          for(Type parameterArgType : parameterArgTypes){

              Class parameterArgClass = (Class) parameterArgType;
              System.out.println("parameterArgClass = " + parameterArgClass);
          }
        }
}
 }

 


输出
genericParameterTypes:[Ljava.lang.reflect.Type;@2f17b4f2
aType:java.util.List<java.lang.String>
parameterArgClass = class java.lang.String



代码输出"parameterArgType= class java.lang.String"。

 Type[]数组 parameterArgTypes包含一项 -一个代表类java.lang.String Class实例 。 Class实现了 Type接口。

11.4 泛型字段类型

可以访问public字段的泛型类型。字段即类的成员变量-静态的或实例变量。下面是一个例子,类有一个实例变量stringList.

public class MyClass {
         public List<String> stringList =null;
}
Field field = MyClass.class.getField("stringList");
Type genericFieldType = field.getGenericType();  
if(genericFieldType instanceof ParameterizedType){
         ParameterizedType aType = (ParameterizedType) genericFieldType;
         Type[] fieldArgTypes = aType.getActualTypeArguments();
         for(Type fieldArgType : fieldArgTypes){
            Class fieldArgClass = (Class) fieldArgType;
            System.out.println("fieldArgClass = " + fieldArgClass);
          }
}

代码将输出"fieldArgClass = class java.lang.String"。

 Type数组fieldArgTypes包含一项 – 一个代表类java.lang.String Class实例 。 Class实现了 Type接口。


posted on 2018-07-13 13:18  2637282556  阅读(97)  评论(0编辑  收藏  举报