获取泛型类的真实参数

获得某个类的泛型

package com;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;


import org.springframework.core.ResolvableType;


interface Service2<N, M> {
}
class ABService2 implements Service2<A, B> {}


public class TestGenericClass2 {
	private Service<C, D> cdService;
	
	public static void main(String[] args) {
		//获取ABService2实现的第一个接口(从0开始计数) 即Service2<A, B>
		ParameterizedType parameterizedType = (ParameterizedType) ABService2.class.getGenericInterfaces()[0];
		System.out.println(parameterizedType);
		//从Service2<A, B> 获得第0个参数 即A
		Type genericType = parameterizedType.getActualTypeArguments()[0];
		System.out.println(genericType);
		System.out.println("*************");
		//下面的可以获得被aop代理之前的类型
		//ClassUtils.getUserClass(myClass);
		ResolvableType resolvableType1 = ResolvableType.forClass(ABService2.class);  
		
		Class c=resolvableType1.as(Service2.class).getGeneric(0).resolve();
		Class d=resolvableType1.getInterfaces()[0].getGeneric(0).resolve();
		System.out.println("c   "+c);
		System.out.println("d   "+d);
		//上面的c与d一样 说明resolvableType1.as(Service2.class)与resolvableType1.getInterfaces()[0]
		//是一样的 都是返回resolvableType1 实现的某个接口
		
		System.out.println("__________");		
	}
}
输出:
com.Service2<com.A, com.B>
class com.A
*************
c   class com.A
d   class com.A
---------------

上面代码里,*************之前的是使用jdk的原始api,之后是使用spring为我们通过的泛型api


使用jdk原始的api,似乎有个问题,那就是如果,如果目标类是继承( 而不是实现)了某个泛型类,那就(似乎)没法获得参数类型了
(这个,我也不确定,如果诸位谁知道,麻烦告诉小弟一声)
package com;


import org.springframework.core.ResolvableType;


interface Service3<N, M> {}
class ServiceImpl3<N,M> implements Service<N, M>{}

class C3 {}
class D3 {}

class CDService3 extends ServiceImpl<C3, D3> {}

public class TestGenericClass3 {
	
	public static void main(String[] args) {
		ResolvableType resolvableType1 = ResolvableType.forClass(CDService3.class);  
		Class c=resolvableType1.as(ServiceImpl.class).getGeneric(0).resolve();
		System.out.println("c   "+c);
	}
}
输出
c   class com.C3
***********

获得成员变量的泛型类型

package com;

import org.springframework.core.ResolvableType;
import org.springframework.util.ReflectionUtils;

interface Service4<N, M> {}
class ServiceImpl4<N,M> implements Service<N, M>{}

class C4 {}

class D4 {}

class CDService4 extends ServiceImpl4<C4, D4> {
}


public class TestGenericClass4 {
	private Service<C, D> cdService;
	
	public static void main(String[] args) {


		ResolvableType resolvableType2 =  
                ResolvableType.forField(ReflectionUtils.findField(TestGenericClass.class, "cdService")); 
		System.out.println(resolvableType2.getGeneric(0).resolve());
			
	}
}
输出:
class com.C


在含泛型的父类中,获得子类的参数

说的很模糊,大家看代码:
package com;

import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;

interface Service<N, M> {
}
class ServiceImpl<N,M> implements Service<N, M>{
	private Class<?> entityN;
	private Class<?> entityM;
	
	public ServiceImpl(){
		System.out.println("this is "+this.getClass());
		//用于避过aop 获得原始的类型
		Class<?> childClass=ClassUtils.getUserClass(this.getClass());
		if (childClass.equals(this.getClass())) {
			System.out.println("一样");
		}
		ResolvableType resolvableType1 = ResolvableType.forClass(childClass);  
		entityN=resolvableType1.as(ServiceImpl.class).getGeneric(0).resolve();
		entityM=resolvableType1.as(ServiceImpl.class).getGeneric(1).resolve();
		System.out.println(entityN+"  **  "+entityM);
	}
}
class A {}

class B {}


class ABService extends ServiceImpl<A, B> {


}


public class TestGenericClass {
	
	public static void main(String[] args) {
	
		Service<A, B> abService= (Service<A, B>) new ABService();
		System.out.println("************* "+abService);		
	}
}
输出
this is class com.ABService
一样
class com.A  **  class com.B
************* com.ABService@3358fd70


关于更多的泛型资料,请见参考资料
顺便多说一句,开涛哥真牛。
感谢glt。




参考资料

http://jinnianshilongnian.iteye.com/blog/1993608
### 如何在Java中获取Class对象 为了获得的`Class`对象,在Java中有几种不同的方式可以实现这一目标。一种常见的方式涉及使用反射机制中的`getGenericSuperclass()`方法来访问父信息,进而提取具体的参数。 当尝试从子实例化过程中捕获并传递泛型类的实际参数给父时,可以通过以下代码片段展示具体操作: ```java // 假设有一个 Base<T> public class Base<T> { private Class<T> type; public Base(Class<T> type) { this.type = type; } protected void printType() { System.out.println(type); } } // 定义一个继承自Base<String>的具体子 SubString public static class SubString extends Base<String> { // 构造函数调用super传入String.class作为type参数 public SubString() { super(String.class); // 显式提供的实际 } } ``` 上述例子展示了如何显式地向父构造器传递的实际[^1]。然而,如果希望自动推断而不是手动指定,则可采用另一种基于反射的方法: ```java import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public abstract class GenericHelper<T> { @SuppressWarnings("unchecked") protected final Class<T> clazz; protected GenericHelper(){ Type superclass = getClass().getGenericSuperclass(); if(superclass instanceof ParameterizedType){ ParameterizedType parameterizedType = (ParameterizedType) superclass; Type[] actualTypes = parameterizedType.getActualTypeArguments(); if(actualTypes.length > 0 && actualTypes[0] instanceof Class<?>){ clazz = (Class<T>)actualTypes[0]; }else{ throw new RuntimeException("无法解析泛型类"); } }else{ throw new RuntimeException("未找到"); } } } ``` 这段代码利用了`getClass().getGenericSuperclass()`返回的对象,并将其转换为`ParameterizedType`以便能够调用`getActualTypeArguments()`方法来获取真实泛型类参数[^4]。 对于某些复杂场景下可能还需要考虑更多细节处理,比如多层嵌套等情况下的适配问题。但是以上两种基本模式已经覆盖了许多常见的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值