java - Typesafe forName 类加载

标签 java generics

如何调用 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。

最佳答案

首先你可能想要一个完整的通用 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<Integer> .例如,如果它是 Callable<String> ,程序毫无问题地运行所有的类型转换,直到很晚才爆炸 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<Integer> 的类,它立即在那里抛出异常。我们的类型转换经过“检查”,程序是类型安全的。

关于java - Typesafe forName 类加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6197802/

相关文章:

Java 泛型 - 类型删除的问题?

Java TreeSet.add() 不遵循 PECS 原则问题(泛型)

带有货币符号的 Java String.format

java - 在 JDK6 而不是 7 下编译的相互自引用类型参数?

java - 在最大化屏幕上调整 JFreeChart.ChartPanel 的大小

java - Java Applet 中开箱即用的 SSL

generics - Swift 要求两个泛型是同一类型

java - 为什么我不能使用类的实现作为参数来覆盖方法

java - ServletRegistration url 映射与 Spring DispatcherServlet 冲突

java - 获取 'java.lang.UnsatisfiedLinkError' : no lwjgl in java. 库.path