【问题标题】:Typesafe forName class loadingTypesafe forName 类加载
【发布时间】:2011-06-03 15:49:30
【问题描述】:

当结果是泛型类型时,我如何调用Class.forName()?通常我可以使用asSubclass(),但在这里我看到的唯一方法是强制转换,当其他所有内容都使用泛型很好地键入时,这种方法会很突出并让我烦恼。

场景是这样的:

有一个带有一个入口点主类的 .jar,它有一个 main()。它需要一个类名选项(以及其他一些,这里不相关)。给定的类实现了Callable<Integer>。此类已加载、初始化和启动。

这是我需要的示例:

Class<? extends Callable<Integer>> clazz = (Class<? extends Callable<Integer>>) Class.forName(options.valueOf(className)).asSubclass(Callable.class);

有什么办法可以去掉那个演员表吗?

使用 SE6。

【问题讨论】:

    标签: java generics


    【解决方案1】:

    首先你可能想要一个完整的通用Class

    Class<Callable<Integer>> classCI = ...;
    

    那么java类型系统就没有问题了

    Class<? extends Callable<Integer>> clazz =     
        Class.forName(options.valueOf(className))
        .asSubclass(classCI);
    

    我们怎样才能得到classCI?我们可以通过未经检查的演员来作弊

    Class<Callable<Integer>> classCI = (Class<Callable<Integer>>)Callable.class;
    

    这本质上是不安全的。必须有外力来确保className 真的是Callable&lt;Integer&gt;。例如,如果它是Callable&lt;String&gt;,则程序运行所有的演员表都没有任何问题,并且它只是在很晚才调用Integer call() 时才爆炸,并且错误消息将非常具有误导性。

    如果无法静态分析强制转换成功也没关系:

    Object o = ...;
    String s1 = (String)o; // may fail, no javac warning
    String s2 = String.class.cast(o); // may fail, no javac warning
    

    只要在运行时强制转换失败时立即抛出异常。

    为了类型安全,我们必须主动检查className的泛型类型

    @SuppressWarning( "unchecked" )
    Class<? Callable<Integer>> getClass(String className)
    {
        Class clazz = Class.forName(className);
        via reflection, check generic super interfaces of clazz
        if there's no Callable<Integer> super interface
            throw "className is not a Callable<Integer>"
    
        // we have *checked*, the following cast is safe
        return (Class<? Callable<Integer>>)clazz; 
    }
    

    我们有理由在这里禁止“未检查”,因为实现检查以确保如果className 并不真正表示实现Callable&lt;Integer&gt; 的类,它会立即抛出异常在那里。我们的演员表是“检查”的,程序是类型安全的。

    【讨论】:

    • +1 : 天哪,我真的很想适应泛型,这样我就可以理解这里发生了什么。
    • 仅供参考,演员 Class> classCI = (Class>)Callable.class 由于某种原因不起作用。无论如何,因为我通过反射检查了 Callable ,所以没什么大不了的,如果你想编辑它,只是需要考虑一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    相关资源
    最近更新 更多