我有以下类层次结构:
public abstract class MyParentObject {}
public abstract class MyObject<T> extends MyParentObject {}
public abstract class MyParentContainer<T extends MyParentObject> {
private Class<T> valueType;
protected MyParentContainer(Class<T> valueType) {
this.valueType = valueType;
}
}
public abstract class MyObjectContainer<T extends MyObject<?>> extends MyParentContainer<T> {
protected MyObjectContainer(Class<T> valueType) {
super(valueType);
}
}
到目前为止,这个工作正常。有几个子类MyObject
和几个容器类,其中一些子类为valueType
,例如
public class IntObject extends MyObject<Integer> {}
public class IntContainer extends MyObjectContainer<IntObject> {
public IntContainer() {
super(IntObject.class);
}
}
现在,我需要实现一个容器,尽管该容器可与的子集混合使用MyObject
。
public class AllObjectContainer extends MyObjectContainer<MyObject<?>> {
public AllObjectContainer() {
super(MyObject.class); // compile error here
}
}
这不会编译,因为“未定义构造函数MyObjectContainer <MyObject>(Class)”。无法将“ MyObject.class”转换为“ Class>”。
为了解决这个问题,我可以使用原始类型:
public class AllObjectContainer extends MyObjectContainer<MyObject<?>>
为public class AllObjectContainer extends MyObjectContainer<MyObject>
尽管由于类型擦除而产生了后果,所以我不喜欢这种解决方案。
或者,我可以通过以下方式启用投射
protected MyObjectContainer(Class<T> valueType) {
为protected MyObjectContainer(Class<? extends T> valueType) {
(添加? extends
)super(MyObject.class)
为super((Class<? extends MyObject<?>>) MyObject.class)
此方法有效,但是强制转换标记为未选中,并且更改MyMiddleContainer
-Constructor会对扩展它的其他类具有潜在的副作用。
有更好的解决方案吗?
关于反射的评论以及此代码不是最佳实现的标志,这些评论是真实有效的,偶然发现此答案的每个人都应阅读并考虑它们。
但是,在我的情况下,不可能完全消除反射,因为该Class
值已传递给另一个不受我控制的类-是否好是另一个问题(我想答案是“否”)。 '),但不在此问题的范围内。
我通过以下方式解决了我的问题:
valueType
从构造函数中删除了参数protected abstract Class<T> getValueType();
到MyParentContainer
然后,我通过以下方式实现了该方法:
public class IntContainer extends MyObjectContainer<IntObject> {
protected Class<T> getValueType() {
return IntObject.class;
}
}
public class AllObjectContainer extends MyObjectContainer<MyObject<?>> {
protected Class<T> getValueType() {
return (Class<MyObject<?>>) (Class<?>) MyObject.class;
}
}
双重演员表并不漂亮,我完全意识到这一点。但是它处于受限的位置,显然可以进行投射,并且可以修复“无法投射”错误。