Java 创建使用反射创建对象的模板方法

Java 创建使用反射创建对象的模板方法,java,generics,reflection,Java,Generics,Reflection,我有一个模板方法,需要使用反射实例化具有给定类名字符串的类对象。这种情况有点复杂,因为返回的类是一个接口的实现,该接口也使用类型变量。我想传递类名字符串和接口类型变量的类型,并创建类对象。下面是一个示例方法签名: <T> Class<? extends Foo<T>> createClassObject(String className, Class<T> classTypeVariable); Class如果返回的类应该是泛型的(Bar扩展F

我有一个模板方法,需要使用反射实例化具有给定类名字符串的类对象。这种情况有点复杂,因为返回的类是一个接口的实现,该接口也使用类型变量。我想传递类名字符串和接口类型变量的类型,并创建类对象。下面是一个示例方法签名:

<T> Class<? extends Foo<T>> 
createClassObject(String className, Class<T> classTypeVariable);

Class如果返回的类应该是泛型的(
Bar扩展Foo
或诸如此类),那么我很有信心这是不可能的,因为(由于擦除),类型系统无法在运行时检查
Class.forName(…)的类
返回的是
,而不是
或其他东西。(实际上只有一个
Class
对象表示所有
Bar
类型,但是类型系统没有这种表示,因此它假装
Class
Class
是完全不同的对象,具有不同的类型。)您可以得到的最接近对象是这样的:

<T> Class<? extends Iterable<T>> createClassObject
        (final String className, final Class<T> clazz) throws Exception
    { return Class.forName(className).asSubclass(getIterableTClass(clazz)); }

@SuppressWarnings("unchecked")
<T> Class<? extends Iterable<T>> getIterableTClass(final Class<T> clazz)
    { return (Class<? extends Iterable<T>>)(Class<?>)Iterable.class; }

Class如果返回的类应该是泛型的(
Bar扩展Foo
或诸如此类),那么我很有信心这是不可能的,因为(由于擦除),类型系统无法在运行时检查
Class.forName(…)的类
返回的是
,而不是
或其他东西。(实际上只有一个
Class
对象表示所有
Bar
类型,但是类型系统没有这种表示,因此它假装
Class
Class
是完全不同的对象,具有不同的类型。)您可以得到的最接近对象是这样的:

<T> Class<? extends Iterable<T>> createClassObject
        (final String className, final Class<T> clazz) throws Exception
    { return Class.forName(className).asSubclass(getIterableTClass(clazz)); }

@SuppressWarnings("unchecked")
<T> Class<? extends Iterable<T>> getIterableTClass(final Class<T> clazz)
    { return (Class<? extends Iterable<T>>)(Class<?>)Iterable.class; }

ClassNo,如果没有任何警告或@SuppressWarnings注释的使用,就无法实现这一点。这是因为Class.forName()将被类型化为Class。任何试图将其转换为更具体的内容的尝试(例如,类似于
ClassNo的内容),如果没有任何警告或使用@SuppressWarnings注释,就无法实现这一点。这是因为Class.forName()将被类型化为Class。任何试图将其转换为更具体的内容的尝试(例如,类似于
Class的东西是可以做到的。在NetBeans IDE 7中,我没有收到任何警告

更正:很抱歉,这无法工作,没有类构造。当然,您可以使用类加载器、代理类或ASM

public class Bar<T> extends Foo<T> {
}
公共类栏扩展了Foo{
}
这真的是逻辑和简单的。线索可能是在做一个链接的newInstance()


public类是的,可以做到。在NetBeans IDE 7中,我没有收到任何警告

更正:很抱歉,这无法工作,没有类构造。当然,您可以使用类加载器、代理类或ASM

public class Bar<T> extends Foo<T> {
}
公共类栏扩展了Foo{
}
这真的是逻辑和简单的。线索可能是在做一个链接的newInstance()


public类不应该
classTypeVariable
Class
而不是
t
的一个实例?顺便问一下,你真的是在运行时创建一个类还是只是查找它?或者你想创建该类的一个实例,即对象?@Thomas,我使用Class.forName()的返回结果这是一个类对象。顺便问一下,从StackOverflow网站的主页上,我可以看到几乎没有答案,但当我打开问题本身的页面时,我看不到任何答案?我只能看到与问题相关的评论。我是否遗漏了什么,或者这是我需要回家的迹象?@jilt3d:我在这页上看到了答案早些时候,但它是错误的(它返回了
T
而不是
)。大概发布该答案的人自己意识到它是错误的,因此将其删除。
classTypeVariable
不应该是
Class
而不是
t
的一个实例吗?顺便问一下,你真的是在运行时创建一个类还是只是查找它?或者你想创建该类的一个实例,即对象?@Thomas,我使用Class.forName()的返回结果这是一个类对象。顺便问一下,从StackOverflow网站的主页上,我可以看到几乎没有答案,但当我打开问题本身的页面时,我看不到任何答案?我只能看到与问题相关的评论。我是否遗漏了什么,或者这是我需要回家的迹象?@jilt3d:我在这页上看到了答案早些时候,但它是错误的(它返回了一个
T
而不是一个
)。可能是发布该答案的人自己意识到它是错误的,因此将其删除。可以使用
Class.asSubclass()将
转换为更具体的内容
,例如,如果它是一个字符串类,我可以执行
class.forName(className).asSubclass(string.class)
。在这种情况下它不起作用,因为子类(
Foo
)是参数化的。@Kevin K:这正是我想做的!可以使用
Class.asSubclass()
类转换为更具体的对象,例如,如果它是字符串类,我可以执行
Class.forName(className).asSubclass(string.Class)
。在这种情况下,它不起作用,因为子类(
Foo
)是参数化的。@Kevin K:这正是我想做的!