Java 协作泛型类 : can we avoid unchecked cast?

标签 java generics compiler-errors

我有两个抽象的泛型类。他们合作,因此相互依赖。偶尔需要通过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) 在类型 AbstractB> 不适用于参数 (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/

相关文章:

java - 请参阅调试期间真实设备中的共享首选项 xml 文件

c# - 对于通用抽象对象工厂,继承不能正常工作

c++ - 使用 C++ 绑定(bind)编译 OpenCL

java - JGraphT - 将 BFS 应用于 WeightedGraph

java - 使 openJPA 仅缓存选定的表

java - 通过另一个 arraylist 对象的方法将字符串添加到 arraylist

java - 类型转换为嵌套在泛型类中的类

Java 泛型 - 编译错误

java - 在java中找不到符号,编译时两个.java文件都在同一个目录中

c - 为什么静态变量不能用其他变量的值来初始化?