在实际工作当中,为了方便和通用性,我们常常会定义泛型类。也就是类型参数化。
Java在编译的时候实际上有类型擦出的,也就是泛型只是在写代码的时候为了方便阅读才显示的列在那里,而字节码里边却是没有该类型信息的。事实上我们定义泛型类以后又会需要获取泛型的class,这该怎么解决呢?
本文给出如下解决方案,如下是笔者工作中的一个实际例子的部分代码,省去业务部分。
首先定义泛型类,我们让该类为抽象类。
public abstract class BaseContext<S extends Annotation,A extends Annotation> { // 获取第i个泛型的类型 public Class<?> getActualTypeArgument(int i ) { { Class<?> clazz = this.getClass(); // 由于本类是抽象类,所以this 一定是其子类的实例化对象 Class<?> entitiClass = null; // 定义返回的class Type genericSuperclass = clazz.getGenericSuperclass(); // 利用反射机制的获取其泛化的超类,实际上也就是带有具体的S 和A的类型的超类 if (genericSuperclass instanceof ParameterizedType) { // 如果本类实现了参数化接口 // 获取所有的参数化的类型 Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments(); if (actualTypeArguments != null && actualTypeArguments.length > i ) { entitiClass = (Class<?>) actualTypeArguments[i]; } } return entitiClass; } } }
应用办法: 本例中Component 和 AutoWired 是自定义的注解
public class MyAppcontext extends BaseContext<Component,AutoWired> { public MyAppcontext() { super(); } }
编写测试代码:
MyAppcontext myAppcontext = new MyAppcontext(); Class<?> actualTypeArgument = myAppcontext.getActualTypeArgument(1); System.out.println(actualTypeArgument);
输出内容为:
interface com.bw.AutoWired
以上是需要把类进行实例化才能得到泛型,那么是否有办法在静态的情况也得到类型呢?办法是有的。
步骤如下:
1、将上述代码中的 public Class<?> getActualTypeArgument(int i ) {} 函数修改为
public static Class<?> getActualTypeArgument( Class<?> clazz,int i ) {
// 注释掉下边这行代码
// Class<?> clazz = this.getClass();
}
2、继承类不变
3、使用的时候代码如下即可:
Class<?> actualTypeArgumentStatic = MyAppcontext.getActualTypeArgument(MyAppcontext.class,0); System.out.println("---------- : " + actualTypeArgumentStatic);
最后输出代码为:
interface com.bw.AutoWired