我有一个如下所示的课程:
class FooClassAnalyser<T extends Foo> extends ClassAnalyser<T>
(其中ClassAnalyser
是许多具体实现的抽象基类; FooClassAnalyser
是一个专门针对T
扩展Foo
的案例的具体实现。 {1}})。它有一个如下所示的构造函数:
FooClassAnalyser(Class<T> classToAnalyse)
在另一个类中,我有ClassAnalyser
的静态工厂方法,根据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
不同,这个&#34;实例通过反射&#34; Java的类型系统是不可见的。特别是,直接将classToAnalyse
作为参数传递给FooClassAnalyser
的构造函数会因类型不匹配而失败,因为Java并不知道classToAnalyse
实际上是{{1} }}
我到目前为止找到的最佳解决方案是使用未经检查的强制转换来使Class<U extends Foo>
成为classToAnalyse
(实际已检查,但Java&#39 ; s不知道它被检查过)。这至少可以将它作为参数传递给Class<? extends Foo>
,并获得一个new FooClassAnalyser
对象作为回报。然而,问题是,这并没有转换回FooClassAnalyser<?>
,因为Java并没有认识到转换ClassAnalyser<U>
具有不同的通用绑定但是并没有这样做。改变classToAnalyse
对象仍然是同一个对象的事实(因此仍然是Class
);换句话说,所有Java都可以看到它是Class<U>
,它不能识别也是FooClassAnalyser<?>
,因此转换回来需要另一个未经检查的强制转换。结果是编译和运行的代码,但有很多关于类型安全的警告。
我尝试过的大多数其他事情都是语法错误(例如FooClassAnalyser<U>
类型的变量无法直接声明; Java没有正确解析它。应该指出的是,我实际上在任何时候都没有Class<U extends Foo>
类型的对象;我试图分析类本身,因此只能使用U
个对象。
是否可以以类型安全的方式编写这样的代码?
答案 0 :(得分:0)
我的问题是,与
instanceof
不同,这种“反射实例”对于Java类型系统是不可见的。特别是,直接将classToAnalyse
作为参数传递给FooClassAnalyser
的构造函数会因类型不匹配而失败,因为Java不知道classToAnalyse
实际上是Class<U extends Foo>
。
只要您将Class<U>
传递给constructClassAnalyser
,就会发生这种情况。您没有为我们提供太多代码,因此我无法为您编写明确的解决方案;但是,如果您能找到一种方法将U
传递给constructClassAnalyser
而不是Class<U>
,那将会更加简单。
static <U> ClassAnalyser<U> constructClassAnalyser(U objectToAnalyse)
要检查其课程,您可以使用objectToAnalyse#getClass
;如果instanceof
返回U extends Foo
,您还可以使用objectToAnalyse instanceof Foo
验证true
,然后根据需要将其投放到相应的班级。