【译】9. Java反射——泛型
原文地址:http://tutorials.jenkov.com/java-reflection/generics.html
========================================================================================
我经常在一些文章和论坛中看有人说Java泛型信息都会在编译时被擦除,所以你不能在运行时访问任何相关的信息。这也不完全对。在运行时,在少数情况下也是可以访问到泛型信息的。实际上,这些情况中已经满足了我们对Java泛型信息的需求。本文将解释这几种情况。
下面是本文所涵盖的主题列表:
- The Generics Reflection Rule of Thumb ()
- Generic Method Return Type (方法返回值类型的泛型)
- Generic Method Parameter Types (方法参数类型的泛型)
- Generic Field Types (字段类型的泛型)
========================================================================================
- The Generics Reflection Rule of Thumb
使用Java泛型无外乎就下面两种情况中的一种:
- Declaring a class/interface as being parameterizable. (声明类、接口参数化)
- Using a parameterizable class.(使用参数化的类)
当你写一个类或者接口的时候,你可以指定它可以被参数化。java.util.List接口就是这种用法。你可以使java.util.List参数化的创建一个String的列表,而不是创建一个Object的列表。
当在运行时检查参数化类型它自己的类型时,如java.util.List,没有办法知道它具体被参数化成了什么类型。这样也合理,因为在同一应用程序中参数化的类型可以是所有类型。但是,当你检查用参数化类型声明的方法或者字段时,你可以知道它们在运行时参数化成了什么类型。简而言之:
在运行时,你不会知道参数化类型它自己的类型,但是你能知道用了参数化类型的字段和方法的类型。换句话说,它们有具体的参数类型。
下面的部分我们将更进一步的来看这几种情况。
========================================================================================
- Generic Method Return Types
如果你获得了java.lang.reflect.Method对象,你也是有可能获得它的返回值类型的泛型信息的。这不会是任何参数化类型的Method对象,除了在类里面使用了参数化类型。你可以去看“Java泛型:方法”来了解如何获取Method对象。下面是一个例子,类中有参数化返回值类型的返回值:
public class MyClass {
protected List<String> stringList = ...;
public List<String> getStringList(){
return this.stringList;
}
}
在这种情况下,可以取得getStringList()方法的泛型返回值类型。换句话说,是可以检测到getStringList()方法返回的是List<String>类型而不仅仅是List。下面是如何来取:
Method method = MyClass.class.getMethod("getStringList", null);
Type returnType = method.getGenericReturnType();
if(returnType instanceof ParameterizedType){
ParameterizedType type = (ParameterizedType) returnType;
Type[] typeArguments = type.getActualTypeArguments();
for(Type typeArgument : typeArguments){
Class typeArgClass = (Class) typeArgument;
System.out.println("typeArgClass = " + typeArgClass);
}
}
这段代码将会打印出“typeArgClass = java.lang.String”.Type[ ]类型的数组typeArguements中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。
========================================================================================
- Generic Method Parameter Types
在运行时,你也可以用Java反射机制访问泛型参数的类型。下面是一个例子,类里面有一个参数化类型的参数:
public class MyClass {
protected List<String> stringList = ...;
public void setStringList(List<String> list){
this.stringList = list;
}
}
你可以像这样来访问其方法参数的参数化类型:
method = Myclass.class.getMethod("setStringList", List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
for(Type genericParameterType : genericParameterTypes){
if(genericParameterType instanceof ParameterizedType){
ParameterizedType aType = (ParameterizedType) genericParameterType;
Type[] parameterArgTypes = aType.getActualTypeArguments();
for(Type parameterArgType : parameterArgTypes){
Class parameterArgClass = (Class) parameterArgType;
System.out.println("parameterArgClass = " + parameterArgClass);
}
}
}
这段代码将会打印出“parameterArgType = java.lang.String”。Type[ ]类型的数组parameterArgTypes中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。
========================================================================================
- Generic Field Types
也可以访问公有字段的泛型类型。字段是类的成员变量——要么是静态变量,要么是实体变量。你可以去看“Java泛型:字段”来了解如何获取Field对象。下面是一个很早之前的例子,类中有有一个叫stringList的实体字段:
public class MyClass {
public List<String> stringList = ...;
}
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 = java.lang.String”。Type[ ]类型的fieldArgTypes数组中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。
========================================================================================
- 目录
这是一个本教程到目前为止涵盖的主题列表:
- Java反射——引言
- Java反射——Class对象
- Java反射——构造函数
- Java反射——字段
- Java反射——方法
- Java反射——Getter和Setter
- Java反射——私有字段和私有方法
- Java反射——注解
- Java反射——泛型
- Java反射——数组
- Java反射——动态代理
- Java反射——类的动态加载和重新加载
(敬请期待下一篇翻译)
【译】9. Java反射——泛型的更多相关文章
- 【译】1. Java反射——引言
原文地址:http://tutorials.jenkov.com/java-reflection/index.html *By Jakob Jenkov Java的反射机制使得它可以在运行时检查类.接 ...
- 【译】2. Java反射——Class对象
原文地址:http://tutorials.jenkov.com/java-reflection/classes.html ====================================== ...
- 【译】3. Java反射——构造函数
原文地址:http://tutorials.jenkov.com/java-reflection/constructors.html ================================= ...
- 【译】4. Java反射——字段
原文地址:http://tutorials.jenkov.com/java-reflection/fields.html ======================================= ...
- 【译】5. Java反射——方法
原文地址:http://tutorials.jenkov.com/java-reflection/methods.html ====================================== ...
- 【译】6. Java反射——Getter和Setter
原文地址:http://tutorials.jenkov.com/java-reflection/getters-setters.html ============================== ...
- 【译】7. Java反射——私有字段和私有方法
原文地址:http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html =================== ...
- 【译】8. Java反射——注解
原文地址:http://tutorials.jenkov.com/java-reflection/annotations.html ================================== ...
- 【译】10. Java反射——数组
原文地址:http://tutorials.jenkov.com/java-reflection/arrays.html ======================================= ...
随机推荐
- python学习笔记(11)--文件与数据格式化
文件的概念: 文件是数据的抽象和集合,是存储在辅助存储器上的数据序列,文件是数据存储的一种形式,文件的展现形态,文本文件和二进制文件. 文本文件输出: f.txt文件保存:“我是中国人” >&g ...
- static关键字的用法
静态变量和静态方法 static关键字的基本用法: 1.修饰变量:被static修饰的变量属于类变量,可以用类名.变量名来引用,而不用直接new一个对象来引用. 2.修饰方法:被static修饰的方法 ...
- $mount(“#app”)手动挂载
没有el属性时,证明vue还没绑定到特定的dom上,需要延迟加载,则使用.$mount("")进行手动挂载 https://blog.csdn.net/longzhoufeng/a ...
- 关于PHP函数传参的注意点
PHP的实参在传递过程中是顺序传递的,不支持指定参数名传递.怎么理解呢?看下面的代码: function test($name,$age){ echo '姓名:'.$name,' 年纪:'.$age; ...
- How to install rime on Debian
apt-get install ibus ibus-rime librime-data-wubi reboot cp ~/.config/ibus/rime/default.yaml ~/.confi ...
- bzoj-1191(二分图最大匹配)
解题思路:比较裸的一道题,直接跑匈牙利就行了,但是要注意一点,这个兔崽子是在闯关,一道题回答不出来就没了,直接在题目循环那里加一个else break;就行了!!!; #include<iost ...
- Nginx TSL/SSL优化握手性能
L:131
- 【深入Java虚拟机】之一:Java内存模型
[深入Java虚拟机]之:Java内存区域与内存溢出 内存区域 Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域.Java虚拟机规范将JVM所管理的内存分为以下几个 ...
- Redis宕机的问题
在主从模式下宕机要分为区分来看: slave从redis宕机 在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据: 如果从数据库实现了持久化,只要重新假如到主从架构中会实现增 ...
- H.264编码原理以及I帧B帧P帧
前言 ----------------------- H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论依据是:参照一段时间内图像的统计结果表明,在 ...