本文介绍了Typesafe forName类加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

当结果是一个泛型类型时,如何调用 Class.forName()?通常我可以使用 asSubclass(),但在这里我唯一能看到的方法就是演员阵容,如果所有的东西都用泛型很好地输入的话,就会出现bug。



这种情况就像这样: 一个带有一个入口点主类的.jar,它有一个 main()。它需要一个类名的选项(和其他一些,在这里不相关)。给出的类实现 Callable< Integer> 。这个类被加载,修改和放大。

下面是我需要的一个例子:

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

有没有办法摆脱那个演员阵容?



使用SE6。

解决方案

首先,您可能需要一个完整的通用 Class

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

然后java类型系统没有问题

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

我们如何获得 classCI ?我们可以通过未经检查的转换来作弊

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






这本质上是不安全的。必须有外力确保 className 确实是 Callable< Integer> 。例如,如果它是一个 Callable< String> ,程序将毫无问题地在所有的转换中运行,并且只有当 Integer call ()被调用,并且错误信息会很容易让人误解。



没关系,如果不能静态分析转换成功:

  Object o = ...; 
String s1 =(String)o; //可能会失败,无javac警告
String s2 = String.class.cast(o); //可能会失败,没有javac警告

只要在转换失败时立即抛出异常
$ b

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

$的通用类型b
$ b

  @SuppressWarning(unchecked)
Class {
Class clazz = Class.forName(className);
通过反射,检查clazz
的通用超级接口,如果没有Callable< Integer>超级接口
throwclassName不是Callable< Integer>

//我们有* checked *,下面的类型是安全的
return(Class< ;? Callable< Integer>>)clazz;

$ / code>

我们有理由在这里取消unchecked,因为执行如果 className 没有真正表示实现 Callable< Integer> 的类,则检查它立即在那里抛出异常。我们的演员被检查,并且该程序是安全的。

How do I call Class.forName() when the result is a generic type? Usually I can use asSubclass(), but here the only way I see to do it is a cast, which kindof sticks out & bugs me when everything else is nicely typed with generics.

The scenario goes something like this:

There is a .jar with one entry point main class that has a main(). It takes an option of a classname (and some others, irrelevant here). The class given implements Callable<Integer>. This class is loaded, inited & launched.

Here is an example of what I need:

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

Is there any way to get rid of that cast?

Using SE6.

解决方案

First you probably want a full generic Class

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

Then the java type system has no problem with

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

How can we get classCI? We can cheat by unchecked cast

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


This is inherently unsafe. There must be external forces to make sure the className really is a Callable<Integer>. For example if it's a Callable<String>, the program runs through all the casts without any problem, and it only blows up much later when Integer call() is invoked, and the error message will be very misleading.

It's ok if a cast cannot be analyzed statically to succeed:

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

as long as an exception is immediately thrown when the cast fails at runtime.

To be type safe, we must proactively check the generic type of the 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;
}

We are justified to suppress "unchecked" here, because the implementation checks to make sure that if the className doesn't really denote a class implementing Callable<Integer>, it immediately throws an exception right there. Our cast is "checked", and the program is type safe.

这篇关于Typesafe forName类加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 22:16