java 获取泛型的类型

来源:互联网 发布:淘宝新赛欧改折叠钥匙 编辑:程序博客网 时间:2024/06/05 16:28

在写通用的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;>;


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

0 0