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



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

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

是否有可能在Java 1.5中实现此方法而没有任何警告或@SuppressWarnings注释的任何使用?

编辑:示例方法签名编辑感谢Thomas注释

不,如果没有任何警告或使用@SuppressWarnings注释,就无法实现这一点。这是因为Class. forname()将被键入为Class。任何将其强制转换为更具体的内容(例如,类似Class<? extends Foo<T>>的内容)的尝试都会产生与类型擦除相关的警告。如果您尝试强制转换Class.forName(). newinstance(),也会发生同样的情况。

也就是说,我认为这个方法是积极使用@SuppressWarnings的主要例子。我认为在这种情况下使用这个注释没有任何问题。当然,您可能想要添加一些逻辑来检查Class.forName(className)是否扩展了Foo<T>,以确保铸造是合理的。请注意,这种运行时检查不会使方法更加脆弱:当您在方法中调用Class.forName()时,您已经有潜在的运行时类型错误。

如果返回的类应该是通用的(Bar<T> extends Foo<T>或什么的),那么我很有信心,这是不可能的,因为(由于擦除)类型系统没有办法在运行时检查,如果Class.forName(...)返回的类是Class<Bar<T>>,而不是Class<Bar<U>>或其他东西。(实际上只有一个单独的Class对象表示所有的Bar<...>类型,但是类型系统没有相应的表示,所以它假装Class<Bar<T>>Class<Bar<U>>是具有不同类型的完全独立的对象。)你能得到的最接近的东西是这样的:

<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; }

使用未检查强制转换来欺骗编译器,使其认为它有足够的关于Foo<T>(在本例中是Iterable<T>)的信息来执行asSubclass检查。

然而,如果返回的类是不是应该是通用的(Bar extends Foo<String>或什么的),那么我不确定;我从来没有过多地讨论过与此相关的反射部分,尽管我知道它们是存在的。我很确定他们会允许你检查足够的Bar的继承层次结构,以确定它是否真的扩展了Foo<String>,但我真的不知道他们是否会给你一种方法,让编译器意识到你已经这样做了。

可以做到。在NetBeans IDE 7中,我没有得到任何警告。

更正:对不起,这不能工作,没有类构造。当然,你可以使用ClassLoader、代理类或ASM。

public class Bar<T> extends Foo<T> {
}

这真的是合乎逻辑和简单。线索可能是执行链式newInstance()。

    public <T> Class<? extends Foo<T>> createClassObject(String className, Class<T> classTypeVariable) {
    try {
        Class<? extends Class> resultType = Bar.class.getClass();
        return resultType.getConstructor(classTypeVariable).newInstance();
    } catch (InstantiationException ex) {
        throw new IllegalStateException(ex);
    } catch (IllegalAccessException ex) {
        throw new IllegalStateException(ex);
    } catch (IllegalArgumentException ex) {
        throw new IllegalStateException(ex);
    } catch (InvocationTargetException ex) {
        throw new IllegalStateException(ex);
    } catch (NoSuchMethodException ex) {
        throw new IllegalStateException(ex);
    } catch (SecurityException ex) {
        throw new IllegalStateException(ex);
    }
}

相关内容

  • 没有找到相关文章

最新更新