具有泛型对象参数的java类型问题
我有一个抽象类
public abstract class WebserviceIntegration {
//...
}
这在很多类中都会用到,比如
public class Manager extends WebserviceIntegration {
//...
}
现在我已经构建了一个类,它作为泛型参数获取抽象类作为F
参数,它内部有一个方法:
public class NewUserWindow<T, F extends WebserviceIntegration> extends Window {
public NewUserWindow(T objOne, F objTwo) {
//...
saveConnectedBean(objTwo); //no problems here
}
public void saveConnectedBean(F bean) throws MyException{
//...
}
}
如果我创建一个新窗口NewUserWindow<?, Manager> window = new NewUserWindow<>(new OtherClass(), new Manager());
,并保存传递给该窗口的bean,那么一切都很好
现在我想做的是在构造函数中保存一个新的Manager
:
public NewUserWindow(T objOne, F objTwo) {
//...
Manager manager = new Manager();
//... setting manager stuff
saveConnectedBean(manager); //does not compile
}
编译器现在阻止我说saveConnectedBean(F) in NewUserWindow cannot be applied to (my.package.path.Manager)
。
如果我把它换成
saveConnectedBean((F)manager);
它编译,但警告我强制转换未选中
在第一种情况下,为什么编译器不知道我的
Manager
类正在扩展WebserviceIntegration
,这使得它与F
类兼容在第二种情况下,如何进行安全投射?我不能用
manager instanceof F
检查,那我该怎么办
谢谢
# 1 楼答案
也许是这样的。将抽象
save
方法添加到WebserviceIntegration
在
WebserviceIntegration
的每个子类中实现这个方法所以
saveConnectedBean
现在可以接受WebserviceIntegration
它应该是安全的,因为
WebserviceIntegration
的每个子类型都必须实现save
功能或者,可以引入新的方法类型参数
在这种情况下
saveConnectedBean
被限制为仅使用来自WebserviceIntegration
的方法实现,因为实际的子类型未知# 2 楼答案
这不是很清楚,但根据您的问题,我认为失败的代码位于泛型类的构造函数中
1)编译器将
F
声明的调用视为泛型类内的调用,编译器不知道F
的确切类型。别忘了泛型只是编译工件因此,如果在构造函数中实例化
Manager
变量,例如:但是你声明了你的泛型类型,比如
NewUserWindow<?, OtherSubClass> window = ...
它会破坏类型安全2)避免泛型类中的
instanceof
。它在某种程度上违背了通用目的或者,您应该从通用实例的客户端传递
Manager
,例如:根据您的评论:
可以通过执行
NewUserWindow
一个抽象类来实现,该抽象类将返回F
的方法声明为抽象类并通过以下方式实施: