我可以反射式地实例化java中的泛型类型吗?

我可以反射式地实例化java中的泛型类型吗?,java,generics,reflection,Java,Generics,Reflection,可以在Java中反射地实例化泛型类型吗?使用描述的技术,我得到一个错误,因为类标记不能是泛型的。以下面的例子为例。我想实例化实现Creator的Creator的一些子类。实际类名作为命令行参数传入。其思想是能够在运行时指定Creator的实现。有没有其他方法来完成我在这里要做的事情 public interface Creator<T> { T create(); } public class StringCreator implements Creator<Strin

可以在Java中反射地实例化泛型类型吗?使用描述的技术,我得到一个错误,因为类标记不能是泛型的。以下面的例子为例。我想实例化实现Creator的Creator的一些子类。实际类名作为命令行参数传入。其思想是能够在运行时指定Creator的实现。有没有其他方法来完成我在这里要做的事情

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);
}
公共接口创建者{
T create();
}
公共类StringCreator实现了Creator{
公共字符串create(){返回新字符串();}
}
公共类FancyStringCreator实现了Creator{
公共字符串create(){返回新的StringBuffer().toString();}
}
公共静态void main(字符串[]args)引发异常{
Class someClass=Class.forName(args[0]);

/*ERROR*/Class您不需要该行。也不需要构造函数,因为您只是使用默认的构造函数。只需直接实例化该类:

public static void main(String[] args) throws Exception {
        Class<?> someClass = Class.forName(args[0]);
        Creator<String> creator = (Creator<String>) someClass.newInstance();
}
publicstaticvoidmain(字符串[]args)引发异常{
Class someClass=Class.forName(args[0]);
Creator=(Creator)someClass.newInstance();
}
如果你坚持,你只能走到一半:

public static void main(String[] args) throws Exception {
    Class<?> someClass = Class.forName(args[0]);
    Class<? extends Creator> creatorClass = someClass.asSubclass(Creator.class);
    Constructor<? extends Creator> creatorCtor = creatorClass.getConstructor((Class<?>[]) null);
    Creator<String> creator = (Creator<String>) creatorCtor.newInstance((Object[]) null);
}
publicstaticvoidmain(字符串[]args)引发异常{
Class someClass=Class.forName(args[0]);

类不太清楚为什么在这里使用泛型

使用反射实例化对象可能会建议一般使用,但您可能会在某个时候调用
create
,并将结果分配给
字符串
,否则为什么要使用泛型来控制返回类型呢

但是如果您编写了Creator的以下实现:

public class IntegerCreator implements Creator<Integer> 
{
  public Integer create() 
  { 
    ...
  }
}
public类IntegerCreator实现Creator
{
公共整数创建()
{ 
...
}
}

并将其作为参数传入,在调用
create
并分配结果时,您将得到ClassCastException。

这将完成您在提供类型安全性的同时尝试执行的操作。无法避免未选中的警告,但此处完成的类型检查证明其抑制是正确的

  public static void main(String[] args)
    throws Exception
  {
    Class<? extends Creator<String>> clz = load(argv[0], String.class);
    Constructor<? extends Creator<String>> ctor = clz.getConstructor();
    Creator<String> creator = ctor.newInstance();
    System.out.println(creator.create());
  }

  public static <T> Class<? extends Creator<T>> load(String fqcn, Class<T> type)
    throws ClassNotFoundException
  {
    Class<?> any = Class.forName(fqcn);
    for (Class<?> clz = any; clz != null; clz = clz.getSuperclass()) {
      for (Object ifc : clz.getGenericInterfaces()) {
        if (ifc instanceof ParameterizedType) {
          ParameterizedType pType = (ParameterizedType) ifc;
          if (Creator.class.equals(pType.getRawType())) {
            if (!pType.getActualTypeArguments()[0].equals(type))
              throw new ClassCastException("Class implements " + pType);
            /* We've done the necessary checks to show that this is safe. */
            @SuppressWarnings("unchecked")
            Class<? extends Creator<T>> creator = (Class<? extends Creator<T>>) any;
            return creator;
          }
        }
      }
    }
    throw new ClassCastException(fqcn + " does not implement Creator<String>");
  }
publicstaticvoidmain(字符串[]args)
抛出异常
{
Class any=Class.forName(fqcn);
for(类clz=any;clz!=null;clz=clz.getSuperclass()){
对于(对象ifc:clz.getGenericInterfaces()){
if(参数化类型的ifc实例){
ParameteredType pType=(ParameteredType)ifc;
if(Creator.class.equals(pType.getRawType())){
如果(!pType.getActualTypeArguments()[0].equals(类型))
抛出新的ClassCastException(“类实现”+pType);
/*我们已经做了必要的检查以证明这是安全的*/
@抑制警告(“未选中”)

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

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);
}
公共接口创建者{
T create();
}
公共接口StringCreator扩展了Creator{}
公共类StringCreatorImpl实现StringCreator{
公共字符串create(){返回新字符串();}
}
公共类FancyStringCreator实现StringCreator{
公共字符串create(){返回新的StringBuffer().toString();}
}
公共静态void main(字符串[]args)引发异常{
Class someClass=Class.forName(args[0]);

发生错误时,Classclaz.newInstance()和ctor.newInstance()的行为不完全相同。类的newInstance方法较旧,并且与其他反射“方法”不一致调用。不是所有的泛型信息在运行时都会丢失;即使不创建另一个接口,也有足够的空间检查必要的类型信息。只是没有足够的信息让编译器推断正确性。你说得对。我说的(以一种复杂的方式)就是说,没有一个类对象可以代表不同于创建者的创建者。但是你在下面截取的代码似乎是解决这个问题的合理方法。
public class AnotherCreator implements Creator<String> {
    public String create() { return ""; }
}