我有两个抽象的泛型类。他们合作,因此相互依赖。偶尔需要通过this
给对方。我正在尝试找到一种类型安全的方法来执行此操作:
public abstract class AbstractA<T extends AbstractB<? extends AbstractA<T>>> {
protected void foo() {
T aB = createB();
aB.setA(this);
}
/** factory method */
abstract public T createB();
}
public abstract class AbstractB<T extends AbstractA<? extends AbstractB<T>>> {
private T theA;
@SuppressWarnings("unchecked")
public void setA(AbstractA<? extends AbstractB<?>> theA) { // dreamed of parameter list (T theA)
// Unchecked cast from AbstractA<capture#1-of ? extends AbstractB<?>> to T
this.theA = (T) theA;
}
protected T getA() {
return theA;
}
}
我的问题是我是否能找到一种更清洁的方法,这样我就可以避免 AbstractB.setA()
中的未经检查的类型转换。 .我曾希望声明它setA(T theA)
, 但是对它的调用不会编译:方法 setA(capture#1-of ? extends AbstractA我在想我的问题可能与 Java generics compilation error - The method method(Class<capture#1-of ? extends Interface>) in the type <type> is not applicable for the arguments 中讨论的问题有关。 .我不受约束的 Actor 阵容就是从那里得到灵感的。我喜欢 Tom Hawtin 的回复 - 解决问题,但我还没有找到将其应用于我的情况的方法。
我的用户将声明具体的子类并实例化一个
ConcreteA
和任意数量的ConcreteB
年代:public class ConcreteA extends AbstractA<ConcreteB> {
@Override
public ConcreteB createB() {
return new ConcreteB();
}
public void concreteAMethod() {
// ...
}
}
public class ConcreteB extends AbstractB<ConcreteA> {
public void bar() {
ConcreteA a = getA();
a.concreteAMethod();
}
}
(class AbstractA<T extends AbstractB<? extends AbstractA<T>>>
看起来有点复杂;我想我需要它让具体的子类知道彼此的确切类型,但显然它没有给我这个。)
最佳答案
如果我对您的理解正确,这应该会创建您想要的绑定(bind)。
class Demo {
public static void main(String[] args) {
ConcreteA a = new ConcreteA();
ConcreteB b = new ConcreteB();
a.foo(b);
b = (ConcreteB) a.getB();
}
}
abstract class AbstractA<T extends AbstractB<?>>{
private AbstractB<?> b;
public AbstractB<?> getB(){
return b;
}
void foo(AbstractB<?> aB) {
b = aB;
aB.bar(this);
}
}
abstract class AbstractB<T extends AbstractA<?>> {
private AbstractA<?> a;
public AbstractA<?> getA(){
return a;
}
public void bar(AbstractA<?> theA) {
a = theA;
theA.foo(this);
}
}
class ConcreteA extends AbstractA<ConcreteB>{
}
class ConcreteB extends AbstractB<ConcreteA>{
}
我想这就是你自己的结局。我无法删除对 ConcreteB 的强制转换,getB() 根本无法确定它所持有的类型。我现在明白为什么您的声明中有多个通用语句。 :)
如果您愿意,请继续搜索,如果找到答案,请发布您自己的答案,我很乐意看到它。
我希望解决你一半的问题对任何事情都很重要。 ;)
关于Java 协作泛型类 : can we avoid unchecked cast?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35013179/