运维开发网

Java 如何在运行时将类转换为类似于类的东西?

运维开发网 https://www.qedev.com 2020-03-10 11:53 出处:网络 作者:运维开发网整理
我有一个类似于以下的类: class FooClassAnalyser<T extends Foo> extends ClassAnalyser<T> (其中ClassAnalyser是许多具体实现的抽象基类;而FooClassAnalyser是一个专门针对T扩展Foo的情况的具体实现).它有一个如下所示的构造函数: FooClassAnalyser(Class<T> classToAnalyse
我有一个类似于以下的类:

class FooClassAnalyser<T extends Foo> extends ClassAnalyser<T>

(其中ClassAnalyser是许多具体实现的抽象基类;而FooClassAnalyser是一个专门针对T扩展Foo的情况的具体实现).它有一个如下所示的构造函数:

FooClassAnalyser(Class<T> classToAnalyse)

在另一个类中,我有一个ClassAnalysers的静态工厂方法,它根据classToAnalyse的类型调用适当的构造函数:

static <U> ClassAnalyser<U> constructClassAnalyser(Class<U> classToAnalyse)

我想要的功能是检查U instanceof Foo,然后构造一个FooClassAnalyser并返回它,如果是的话.

但是,我无法找到适合Java类型系统的方法.类型擦除意味着我们不能直接用U做任何聪明的事情.但是,我们将classToAnalyse作为参数传递的事实使得可以通过使用反射来测试是否U instanceof Foo:

if (Foo.class.isAssignableFrom(classToAnalyse))

我的问题是,与instanceof不同,这种“反射的实例”对于Java的类型系统是不可见的.特别是,直接将classToAnalyse作为参数传递给FooClassAnalyser的构造函数会因类型不匹配而失败,因为Java不知道classToAnalyse实际上是一个类< U extends Foo>.

到目前为止,我发现的最佳解决方案是使用未经检查的强制转换使classToAnalyse成为一个Class<?延伸Foo> (它实际上已经过检查,但是Java没有意识到已经检查过了).这至少可以将它作为参数传递给新的FooClassAnalyser,并获得一个FooClassAnalyser<?>对象作为回报.然而,问题是,这不会转换回ClassAnalyser< U>,因为Java不会识别出使用不同的通用绑定来构造classToAnalyse,但是不会改变Class对象仍然是相同的对象(因此仍然是一个类< U>);换句话说,所有Java都能看到的是FooClassAnalyser<?>它无法识别也是一个FooClassAnalyser< U>,因此转换回来需要另一个未经检查的强制转换.结果是编译和运行的代码,但有很多关于类型安全的警告.

我尝试过的大多数其他事情都是语法错误(例如,类型为< U extends Foo>的变量不能直接声明; Java不能正确解析它).应该注意的是,我实际上并没有任何类型的U型物体;我试图分析类本身,因此只有Class< U>要使用的对象.

是否可以以类型安全的方式编写这样的代码?

My problem is that unlike instanceof, this “instanceof via reflection” isn’t visible to Java’s type system. In particular, passing classToAnalyse directly as an argument to FooClassAnalyser‘s constructor fails with a type mismatch because Java doesn’t know that classToAnalyse is actually a Class<U extends Foo>.

只要你传递了一个类< U>,就会发生这种情况. to constructClassAnalyser.您没有为我们提供太多代码,因此我无法为您编写明确的解决方案;但是,如果你能找到一种方法将U传递给constructClassAnalyser而不是Class< U>,那将会更加简单.

静态< U> ClassAnalyser< U> constructClassAnalyser(U objectToAnalyse)

要检查它的类,可以使用objectToAnalyse#getClass;如果objectToAnalyse instanceof Foo返回true,你也可以使用instanceof验证U扩展Foo,然后在需要时将其强制转换为各自的类.

0

精彩评论

暂无评论...
验证码 换一张
取 消