当前位置: 代码网 > it编程>编程语言>Java > java怎样动态获取泛型参数的类型

java怎样动态获取泛型参数的类型

2024年09月19日 Java 我要评论
java如何动态获取泛型参数的类型我们都知道java中的泛型其实是伪泛型,java在编译阶段会对变异类型进行擦除,擦出到泛型类的最小上限,编译后得到的class文件里面是没有任何泛型信息的,泛型的控制

java如何动态获取泛型参数的类型

我们都知道java中的泛型其实是伪泛型,java在编译阶段会对变异类型进行擦除,擦出到泛型类的最小上限,编译后得到的class文件里面是没有任何泛型信息的,泛型的控制其实就是java编译器进行的控制,编译阶段进行泛型检查。

那如果我们想在运行时知道泛型类的类型,如何做到呢?

主要用到下面几个api:

1、public type getgenericsuperclass()---class类的方法

2、type[] getactualtypearguments()---parameterizedtype方法

3、public type[] getgenericinterfaces()---class类的方法

  • 我们先定义一个泛型类:
public class father<t> {
}
  • 再定义一个子类:
public class son extends father<string>{
}
  • 先来看看下面代码:
system.out.println(son.class.getgenericsuperclass());
system.out.println(son.class.getsuperclass());
system.out.println(father.class.getgenericsuperclass());
system.out.println(father.class.getsuperclass());

运行结果如下:

从上面运行结果可以看出两点:

(1)通过class类的getgenericsuperclass()是可以获取到泛型信息的;

(2)泛型类本身是无法获取到泛型信息的,只能通过泛型类的子类来获取泛型信息,这也很好解释,因为泛型类比如father类自身,其泛型参数并未确定,自然无法获取泛型信息,而子类的泛型参数类型已经确定,父类泛型信息已经确定,所以可以查询。

具体的查询泛型参数类型的代码如下:

parameterizedtype parameterizedtype = (parameterizedtype) son.class.getgenericsuperclass();
system.out.println(parameterizedtype.getclass().getname());
system.out.println(parameterizedtype);
type[] actualtypearguments = parameterizedtype.getactualtypearguments();
for(type actualtypeargument: actualtypearguments) {
    system.out.println(actualtypeargument.getclass().getname());  
	system.out.println(actualtypeargument); 
} 

运行结果如下:

由上图运行结果可知:

(1)getgenericsuperclass()返回的实际类型为parameterizedtypeimpl,这里面带有父类的泛型类型信息;

(2)获取泛型参数信息是通过parameterizedtype的getactualtypearguments方法,该方法返回的是一个type类型的数据,该数据存放的数据的实际类型为class,也就是我们得到了泛型参数的类信息。

上面讲述的是获取父类的泛型类型,那接口的泛型类型如何获取呢?

  • 先贴一个简单的接口:
public interface itest<t> {
}
  • 我们让son类实现该方法:
public class son extends father<string> implements itest<integer>{
}
  • 获取itest的泛型参数类型的方法如下:
parameterizedtype parameterizedtype = (parameterizedtype) son.class.getgenericinterfaces()[0];
system.out.println(parameterizedtype.getclass().getname());
system.out.println(parameterizedtype);
type[] actualtypearguments = parameterizedtype.getactualtypearguments();
for(type actualtypeargument: actualtypearguments) { 
	system.out.println(actualtypeargument.getclass().getname());
	system.out.println(actualtypeargument); 
} 

运行结果如下:

和泛型类区别就是getgenericsuperclass()方法换成了getgenericinterfaces(),getgenericinterfaces()方法返回的是type[],因为一个类可以实现多个接口,所以想要获取哪个接口的泛型信息,需要指定数据下标,这里son类就实现了一个接口,所以直接son.class.getgenericinterfaces()[0]就可以了。

上面的代码有一个共同点

就是泛型类或者泛型接口已经有一个子类了,通过子类的class信息可以获取到泛型父类或者泛型接口的泛型类型信息,那么如果没有子类,怎么直接获取泛型类的泛型类型信息呢?

很简单,通过匿名内部类(其实还是通过子类).

new father<integer>() {}.getclass().getgenericsuperclass();
new itest<integer>() {}.getclass().getgenericinterfaces())[0];

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com