跳过编译器,获取泛型参数的实际类型

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;

public class GenericTest {

	public static void main(String[] args) throws Exception {
		//泛型类型是给编译器看的,编译成class字节码文件后会丢弃类型信息,所以通过反射是无法知道泛型所存储的实际类型的
		List<String> list = new ArrayList<String>();
		list.add("java");
		//collection.add(20);	//编译报错,因为编译期间严格检查泛型的实际数据类型
		//由上结论可知,既然编译成class文件后不会保存类型信息,那么是不是就可以通过反射的方式存储任意类型的数据呢?
		//示例:通过反射在collection中存储除String以外的数据
		list.getClass().getMethod("add", Object.class).invoke(list,5);
		list.getClass().getMethod("add", Object.class).invoke(list, new Date());
		System.out.println(list.size());	//结果是3
		//用下面的方式去获取元素会报ClassCaseException,因为List中第1和第2条记录都不是String类型,所以取出来的时候会报类型转换异常
		//System.out.println(list.get(1));
		//说明:上面示例只想说明,JAVA中的泛型是提供给编译器检查使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会丢弃“类型”信息,使用程序运行效率不受影响

		//由于无法在运行期间获取某个带类型的集合属性的实际类型,但可以获得方法参数列表中泛型参数的实际类型
		Method method = GenericTest.class.getMethod("getGenericActualType", List.class,Vector.class);
		Type[] types = method.getGenericParameterTypes();
		for(int i = 0; i < types.length; i++) {
			ParameterizedType pt = (ParameterizedType) types[i];
			System.out.print("泛型原始类型: " + pt.getRawType() + "\t");
			System.out.println("泛型实际类型: " + pt.getActualTypeArguments()[0]);
		}
	}

	/*
	 * 获得泛型参数的原始类型,示例方法
	 */
	public static void getGenericActualType(List<Date> list,Vector<String> vector) {

	}
}

通过反编译工具获取GenericTest.class的源代码:


 

时间: 2024-10-26 18:23:52

跳过编译器,获取泛型参数的实际类型的相关文章

java-获取到方法的中泛型参数的实际类型

问题描述 获取到方法的中泛型参数的实际类型 java的泛型在内存中不是不存在的嘛?为什么通过以下的代码可以获取到方法的中泛型参数的实际类型? class GenericTest{ public static void applyVectory(Veectory v1){ } public static void main(String[] args){ Method applyMethod = GenericTest.class.getMethod("applyMethod",Vect

java-Java方法内如何获取参数的实际泛型参数?

问题描述 Java方法内如何获取参数的实际泛型参数? 想在注释处获取参数中泛型T的实际类型的Class对象,如何做呢? 代码如下: public interface MyResultHandler<T> { public Object invoke(ResultSet rs, Class<T> clazz); } public class MyDbUtils { public static <T> Object select(String sql, MyResultHa

利用反射获取方法参数对象的泛型定义

问题描述 利用反射获取方法参数对象的泛型定义 public CommonRsp<AAARsp> hotelCheckAvailability(CommonReq<BBBReq> req) throws Exception; 如何通过反射获取如上方法中的参数泛型定义BBBReq? 解决方案 你这是java语法吗,如果是的话,其实java的泛型本质上是糖衣语法,编译后泛型是会被擦除的.你获取泛型本质上是没有意义的,应该是获取不到的.

Java反射获取方法参数名

问题 在编写一个jws(游戏中心的WEB框架)增强工具的时候,需要得到方法的参数名,而jws本身是可以获取参数名的(不然controller里将请求参数与方法参数绑定的功能也无法实现了). 但使用了jws提供的获取参数名方法时,却出现返回的参数名不正确的问题(只会出现在idea里面): 所以说: 为什么可以获取方法参数? 为什么eclipse和生产环境里不会发生这种问题? 怎样可以正确获取方法的参数名? 问题排查 获取方法参数 众所周知,在java里面,直到java8才可以正式的通过反射获取方法

编写高质量代码改善C#程序的157个建议[优先考虑泛型、避免在泛型中声明静态成员、为泛型参数设定约束]

原文:编写高质量代码改善C#程序的157个建议[优先考虑泛型.避免在泛型中声明静态成员.为泛型参数设定约束] 前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能.基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是对方法的引用.事件本身也是委托,它是委托组,C#中提供了关键字event来对事件进行特别区分.一旦我们开始编写

jquery获取url参数及url加参数的方法_jquery

使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作,下面通过文字说明加代码分析的形式给大家解析,具体详情请看下文. 1.jquery获取url很简单,代码如下: 复制代码 代码如下: window.location.href; 其实只是用到了javascript的基础的window对象,并没有用jquery的知识. 2.jquery获取url参数比较复杂,要用到正则表达式,所以学好javascript正则式多么重要的事情 首先看看单纯的通过javascript是如

用javascript获取地址栏参数

核心提示:本文列举了用javascript获取地址栏参数的三种方法 本文列举了用javascript获取地址栏参数的三种方法: 方法一: <script type="text/javascript"> <!-- String.prototype.getQuery = function(name) {  var reg = new RegExp("(^&)"+ name +"=([^&]*)(&$)"); 

&amp;#106avascript获取地址参数

修改地址后的参数: <script>function getNewUrl(oldurl,paramname,pvalue){    var reg = new RegExp("(\\?|&)"+ paramname +"=([^&]*)(&|$)","gi");    var t=oldurl.match(reg)[0];    var retxt=t.substring(0,t.indexOf("=

Javascript获取地址参数

javascript 修改地址后的参数: <script>function getNewUrl(oldurl,paramname,pvalue){    var reg = new RegExp("(\\?|&)"+ paramname +"=([^&]*)(&|$)","gi");    var t=oldurl.match(reg)[0];    var retxt=t.substring(0,t.inde