java 获取泛型的类型

在写通用的dao的模块的时候, 需要获取具体子类的泛型类型:

比如:父类

public class Father<T, P, K> {

}
子类:

public class Son extends Father<String, Long, Integer>{
}
怎么获取到子类中, 这String, Long, Integer 的三个类型呢?


程序一:

public static void getPt() {
		ParameterizedType type = (ParameterizedType)Son.class.getGenericSuperclass();
		Type[] pts = type.getActualTypeArguments();
		for(Type t : pts) {
			System.out.println(t);
		}
	}

程序二: 

在.class文件中 , Signature属性是可选的定长属性,位于ClassFile(§4.1),field_info(§4.5)或method_info(§4.6)结构的属性表中。在Java语言中,任何类、接口、初始化方法或成员的泛型签名如果包含了类型变量(Type Variables)或参数化类型(Parameterized Types),则Signature属性会为它记录泛型签名信息。

所以我们可以操作字节码来获取Signature属性,从而获取这些具体的类型, 常用的字节码工具有asm, javasist, 这里用javasist(需要导入其jar)

import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.BadBytecode;
import javassist.bytecode.ClassFile;
import javassist.bytecode.SignatureAttribute;

public class Test1 {
	
	public static void main(String[] args) throws NotFoundException, BadBytecode {
		ClassPool cp =new ClassPool(true);
		CtClass ctClass = cp.get("jdk.clazz.Son");//类全路径
		ClassFile classFile = ctClass.getClassFile();
		SignatureAttribute attribute = (SignatureAttribute)classFile.getAttribute("Signature");
		System.out.println(attribute.getSignature());
	}
}
程序输出:Ljdk/clazz/Father<Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Integer;>;


比较:程序一 :简单, 不用导入其他包。 程序二: 需要字节码操作工具,但是更加强大。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值