java - 当参数化类型传递层次结构时,在 Java 中创建泛型类型的实例吗?

标签 java generics inheritance reflection

我一直在阅读问题的答案:

Create instance of generic type in Java?

我已经实现了 Lars Bohl 建议的方法。我对其代码进行了如下修改:

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

public class ParameterizedTypeEg<E> {
    public Class<E> getTypeParameterClass() {
        Type type = getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        return (Class<E>) paramType.getActualTypeArguments()[0];
    }
    private static class StringHome extends ParameterizedTypeEg<String> {
        private String _string;
        StringHome (String string) {
            _string = string;
        }
    }
    public static void main(String[] args)
        throws InstantiationException, IllegalAccessException {
        String str = new StringHome("my string").getTypeParameterClass().newInstance();
        String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();
    }
}

这种方法对于 str 变量效果很好。然后 str2 是用在我看来相同的类型创建的(ParameterizedTypeEg < String >,基本上与 StringHome 相同)。但是,该方法不适用于 str2,并且当我尝试转换 (ParameterizedType) 类型时会抛出 ClassCastException。

尽管对于 str2,我已使用字符串参数化 ParameterizedTypeEg,但 getGenericSuperclass() 返回的内容与 str 非常不同。另外,在方法 str2 中,“this”显示为 ParameterizedTypeEg,而对于 str,“this”是 ParameterizedTypeEg$StringHome。我想这就是问题的根源。为什么 Java 没有看到 str2 的泛型类型也已确定?

当参数化类型通过多个层次结构传递时,我遇到了似乎相同的问题?也就是说,类 B 包含 A,并且我实例化了 B。在 A 中,我无法通过使用上述方法确定 A 的参数化类型来创建 String 对象。该方法在包含层次结构的情况下也会产生异常。这给我带来了一个问题,因为我希望能够通过多个级别的包含和/或继承来传递参数化类型,并在所有情况下使用相同的方法生成泛型类型的实例。

谢谢, 约翰

最佳答案

通过以下更改,您的代码将起作用:

来自

  String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();

   String str2 = new ParameterizedTypeEg<String>(){}.getTypeParameterClass().newInstance();

这将创建 ParameterizedTypeEg 的匿名子类。当你打电话时

getClass().getGenericSuperclass();

在 StringHome 上,您会得到一个 ParameterizedTypeEg < java.lang.String>,这就是您想要的。如果您像以前那样创建 str2,则该调用只会返回 Object,因此尝试将其转换为参数化类型会失败:

Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

创建匿名子类会返回 ParameterizedTypeEg < java.lang.String>

这与 Type Token 中使用的技巧相同。顺便说一句,Google Guice Guave 库中的类。例如,你写

new TypeToken<List<String>>() {}

而不是

 new TypeToken<List<String>>()  

关于java - 当参数化类型传递层次结构时,在 Java 中创建泛型类型的实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18555122/

相关文章:

java - spring kafka 寻找主题中最新的可用消息

java - 在网络应用程序中上传图像

Java时间忽略夏令时规则

java - 扩展通用父级时的值转换

java - 我可以/如何强制 JBoss 和 Eclipse 仅使用一个核心?

java - 带有通配符的列表会导致通用巫毒教错误

java - 什么时候应该使用泛型来定义类型之间的关系?

generics - 如何限制 Rust 中特征的通用实现?

Java 列表和类继承

oop - 继承与聚合