当前位置: 首页 > 面试题库 >

Typesafe forName类加载

长孙硕
2023-03-14
问题内容

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>。例如,如果它是a
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; 
}

我们有理由在这里取消“ unchecked”,因为实现会 进行检查
以确保如果className并没有真正表示实现的类Callable<Integer>,那么它会立即在此处抛出异常。我们的演员表已“检查”,程序是类型安全的。



 类似资料:
  • 我有一个包含倍数. war的。我想把它部署到jboss 6.4.7服务器上。问题是其中一个. war使用了jboss的模块(hibernate-jpa-2.0),但是这个应用需要hibernate-jpa-2.1版本。如何告诉我的战争不使用这个jboss模块。我已经添加了一个jboss部署结构到耳朵/应用程序/META-INF与此排除: 但是不起作用。。 “javax.persistence.ap

  • 框架中所有的类都是通过类加载器(ClassLoader)加载的,通过Loader我们可以实现类的统一管理。下面我们一起来看看Loader提供了哪些加载方法: 1. Loader::import 加载一个类或者加载一个包 方法原型 import( $classPath, $type = IMPORT_APP, $extension=EXT_PHP ) 参数名称 参数说明 $classPath 文件的

  • 加载器,顾名思义,是用于加载元素的,加载的元素可以是库(类),视图文件 , 驱动器 ,辅助函数 , 模型 或其他你自己的文件。 注解 该类由系统自动加载,你无需手工加载。 应用程序"包" 包的视图文件 类参考 应用程序"包" 应用程序包(Package)可以很便捷的将你的应用部署在一个独立的目录中, 以实现自己整套的类库,模型,辅助函数,配置,文件和语言包。 建议将这些应用程序包放置在 appli

  • 如果我有一个内部类声明,例如: 其次是: A$B内部类也会加载吗?如果B内部类没有被声明为“静态”呢?

  • 首先,新建一个配置文件 conf/custom/cron.properties # clean non-active user cron.net.wendal.nutzbook.quartz.job.CleanNonActiveUserJob=0 0/2 * * * ? cron.pkgs=net.wendal.nutzbook.quartz.job 这个文件是定义Job类与cron表达式的关系

  • 数据加密类提供了双向数据加密方式。加密类使用 Mcrypt 库加密数据,所以需要 Mcrypt 扩展才能运行。 设置你的密钥 密钥实际上是一些会控制密码加密过程并且允许被加密的字串被解码的信息片段。实际上,你选择的密钥会提供一个唯一的方法来解密一些被加密的数据,所以你需要非常谨慎的设置你的密钥,如果你想给一些固定的数据加密的话,你最好不要更改这个密钥。 很自然,你需要非常小心的保存你的密钥。如果某