我可以反射性地实例化 Java 中的泛型类型吗? [英] can I reflectively instantiate a generic type in java?

查看:31
本文介绍了我可以反射性地实例化 Java 中的泛型类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在 Java 中反射性地实例化泛型类型?使用此处描述的技术,我收到一个错误,因为类令牌不能通用.以下面的例子为例.我想实例化一些实现 Creator 的 Creator 子类.实际的类名作为命令行参数传入.这个想法是能够在运行时指定 Creator 的实现.有没有其他方法可以完成我在这里尝试做的事情?

Is it possible to reflectively instantiate a generic type in Java? Using the technique described here I get an error because class tokens cannot be generic. Take the example below. I want to instantiate some subclass of Creator that implements Creator. The actual class name is passed in as a command line argument. The idea is to be able to specify an implementation of Creator at runtime. Is there another way to accomplish what I'm trying to do here?

public interface Creator<T> {
    T create();
}
public class StringCreator implements Creator<String> {
    public String create() { return new String(); }
}
public class FancyStringCreator implements Creator<String> {
    public String create() { return new StringBuffer().toString(); }
}
public static void main(String[] args) throws Exception {
    Class<?> someClass = Class.forName(args[0]);
    /*ERROR*/Class<? extends Creator<String>> creatorClass = someClass.asSubclass(Creator.class);
    Constructor<? extends Creator<String>> creatorCtor = creatorClass.getConstructor((Class<?>[]) null);
    Creator<String> creator = creatorCtor.newInstance((Object[]) null);
}

我喜欢 Marcus 的方法,因为它是最简单、最实用的方法,而且没有绕过整个泛型问题.我可以在我的情况下使用它,因为我可以指定传递的类必须是 StringCreator 的子类.但是正如 Ericson 指出的那样,泛型信息仍然存在于类型级别,只是不在运行时级别,因此仍然可以反思地检查给定的类是否实现了正确的泛型类型.

I like Marcus' approach as being the most simple and pragmatic without circumventing the whole generics thing. I can use it in my situation because I can specify that the class passed must be a subclass of StringCreator. But as Ericson pointed out the generic information is still there at the type level, just not at the runtime level so it is still possible to reflectively examine whether a given class implements the correct generic type.

推荐答案

通用信息在运行时丢失.没有与 Creator.class 等效的运行时.您可以在 Creator 和 StringCreator 之间创建一个修复泛型类型的类型:

The generic information is lost in runtime. There is no runtime equivalent of a Creator<String>.class. You could create a type between Creator and StringCreator which fixes the generic type:

public interface Creator<T> {
        T create();
}
public interface StringCreator extends Creator<String> { }
public class StringCreatorImpl implements StringCreator  {
        public String create() { return new String(); }
}
public class FancyStringCreator implements StringCreator  {
        public String create() { return new StringBuffer().toString(); }
}
public static void main(String[] args) throws Exception {
        Class<?> someClass = Class.forName(args[0]);
        Class<? extends StringCreator> creatorClass = someClass.asSubclass(StringCreator.class);
        Constructor<? extends StringCreator> creatorCtor = creatorClass.getConstructor((Class<?>[]) null);
        Creator<String> creator = creatorCtor.newInstance((Object[]) null);
}

但是当然你失去了一点灵活性,因为你不能使用下面的创建者类:

But of course you lose a bit of flexibility, because you cannot use the following creator class:

public class AnotherCreator implements Creator<String> {
    public String create() { return ""; }
}

这篇关于我可以反射性地实例化 Java 中的泛型类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆