我有以下类层次结构:
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(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
-构造函数对扩展它的其他类有潜在的副作用。
有没有更好的解决办法?
2条答案
按热度按时间omqzjyyz1#
关于反射和此代码不是最佳实现的标志的评论是真实有效的,每个偶然发现此答案的人都应该阅读并考虑它们。
然而,在我的例子中,不可能完全消除反射,因为
Class
值被传递给另一个不在我控制之下的类-这是否好是另一个问题(我猜,答案是“否”),但不在这个问题的范围内。我用以下方法解决了我的问题:
删除了
valueType
构造函数中的参数补充
protected abstract Class<T> getValueType();
至MyParentContainer
然后我通过以下方式实现了该方法:双重演员不好看,我完全知道。然而,这是在一个有限的位置,很明显,这是可以投,它修复了“不能投”的错误。
pgx2nnw82#
所以,
MyClass.class
属于类型Class<MyClass>
不是Class<MyClass<?>>
.这其实是一个关于反思的问题。
通常解决反射问题的好办法是不使用反射。
我建议取消使用
Class
并替换为所需操作的接口。然后,如果愿意的话,可以在该接口的特定实现中放置反射污点。