使用反射获得泛型的实际参数

本文详细介绍了如何使用Java反射API获取方法的泛型参数类型。通过具体的代码示例,展示了如何利用ParameterizedType接口的getActualTypeArguments方法来确定泛型参数的具体类型。

今天刚学习的,来加深一下记忆,以免忘记.

package com.test.generic;

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

public class GenericTest {

	public static void main(String[] args) {
		try {
			Method method=GenericTest.class.getMethod("getParamType", Vector.class);
			Type[] types=method.getGenericParameterTypes();
			ParameterizedType pType=(ParameterizedType) types[0];
			System.out.println(pType.getActualTypeArguments()[0]);
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
	public void getParamType(Vector<Date> param){
		
	}
}

 首先得了解几个类:

Method就不多说了.

Type:

public interface Type
Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 从Jdk1.5开始.

 

ParameterizedType:

 

public interface ParameterizedType
extends Type
Type[] getActualTypeArguments()
返回表示此类型实际类型参数的 Type 对象的数组。

注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。

 

返回:
表示此类型的实际类型参数的 Type 对象的数组
抛出:
TypeNotPresentException - 如果任何实际类型参数引用不存在的类型声明
MalformedParameterizedTypeException - 如果任何实际类型参数引用参数化类型,该类型出于某种原因无法被实例化

 

getGenericParameterTypes

public Type[] getGenericParameterTypes()
按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的。如果底层方法不带参数,则返回长度为 0 的数组。

如果形参类型是参数化类型,则为其返回的 Type 对象必须实际反映源代码中使用的实际类型参数。

如果形参类型是类型变量或参数化类型,则创建它。否则将解析它。

 

返回:
按照声明顺序返回表示底层方法的形参类型的 Type 对象数组
抛出:
GenericSignatureFormatError - 如果一般方法签名不符合 Java Virtual Machine Specification, 3rd edition 中指定的格式
TypeNotPresentException - 如果底层方法的所有参数类型都引用不存在的类型声明
MalformedParameterizedTypeException - 如果所有底层方法的参数类型引用无论如何都无法实例化的参数化类型

 

 

我的理解:首先通过反射方法获得特定名称的方法.然后可以按照声明顺序返回 Type 对象的数组,最后获得参数数组中的第一个(在本例中仅此一个)参数.然后可以通过getActualTypeArguments()来得到参数的准确类型.然后syso出来.

Java 中,如果你有一个参数 `Class<T>`,你可以使用反射来创建该类的新实例。`Class<T>` 是 Java 反射 API 中的一个类,它表示一个类的运行时类型信息。通过调用 `newInstance()` 方法(在 Java 9 之后被弃用)或使用 `getDeclaredConstructor().newInstance()` 方法,你可以动态地创建对象。 --- ### ✅ 示例代码:使用 `Class<T>` 创建新对象 ```java public class GenericFactory<T> { private Class<T> clazz; public GenericFactory(Class<T> clazz) { this.clazz = clazz; } public T createInstance() throws Exception { // 使用反射创建对象实例 return clazz.getDeclaredConstructor().newInstance(); } public static void main(String[] args) throws Exception { // 创建一个 GenericFactory 来生成 String 实例 GenericFactory<String> factory = new GenericFactory<>(String.class); String str = factory.createInstance(); System.out.println("创建的字符串对象: " + str); // 输出空字符串 // 创建一个 GenericFactory 来生成自定义类 User 实例 GenericFactory<User> userFactory = new GenericFactory<>(User.class); User user = userFactory.createInstance(); System.out.println("创建的 User 对象: " + user); // 输出 User@... } } class User { public User() { // 默认构造函数 } @Override public String toString() { return "User{}"; } } ``` --- ### 📌 注意事项: 1. **必须有无参构造函数**: - 如果你尝试实例化的类没有无参构造函数,会抛出 `NoSuchMethodException`。 - 示例: ```java class User { public User(String name) { /* ... */ } } ``` 上述类将导致反射创建失败,除非你显式指定构造器。 2. **使用 `getDeclaredConstructor()` 更安全**: - 它可以访问私有构造器(需要配合 `setAccessible(true)`)。 - 推荐替代已弃用的 `newInstance()`。 3. **安全性**: - 由于类型擦除,运行时无法验证实际类型,但使用 `Class<T>` 作为参数可以确保编译时类型安全。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值