不是那么简单的Java递归泛型问题

问题描述 投票:0回答:1

我有很多接口(

Foo
Bar
)、实现这些接口的抽象类(
AbstractFoo
AbstractBar
)以及扩展这些抽象类的类(
FooImpl1
FooImpl2
BarImpl1
BarImpl2
)。接口是泛型的,参数相互指向。一切都在编译,直到我在
AbstractBar
类 (
this.foo.addBar(this);
) 的构造函数中使用通用字段的方法。

现场样品

class Main {
    public static void main(String[] args) {}

    interface Foo<B extends Bar> {
        Set<B> getBars();
    }

    abstract class AbstractFoo<B extends AbstractBar> implements Foo<B> {
        private final Set<B> bars = new HashSet<>();
        
        public void addBar(B bar) {
            this.bars.add(bar);
        }

        @Override
        public Set<B> getBars() {
            return this.bars;
        }
    }

    class FooImpl1 extends AbstractFoo<BarImpl1> {}

    class FooImpl2 extends AbstractFoo<BarImpl2> {}

    interface Bar<F extends Foo> {
        F getFoo();
    }

    abstract class AbstractBar<F extends AbstractFoo<?>> implements Bar<F> {
        private final F foo;

        public AbstractBar(F foo) {
            this.foo = foo;
            // this following line is breaking my head...
            this.foo.addBar(this);
        }

        @Override
        public F getFoo() {
            return this.foo;
        }
    }

    class BarImpl1 extends AbstractBar<FooImpl1> {
        public BarImpl1(FooImpl1 foo) {
            super(foo);
        }
    }

    class BarImpl2 extends AbstractBar<FooImpl2> {
        public BarImpl2(FooImpl2 foo) {
            super(foo);
        }
    }
}
java generics
1个回答
0
投票

导入java.util.HashSet; 导入 java.util.Set;

类主要{ 公共静态无效主(字符串[]参数){}

interface Foo<B extends Bar<?>> {
    Set<B> getBars();
}

abstract class AbstractFoo<B extends AbstractBar<? extends AbstractFoo<B>>> implements Foo<B> {
    private final Set<B> bars = new HashSet<>();
    
    public void addBar(B bar) {
        this.bars.add(bar);
    }

    @Override
    public Set<B> getBars() {
        return this.bars;
    }
}

class FooImpl1 extends AbstractFoo<BarImpl1> {}

class FooImpl2 extends AbstractFoo<BarImpl2> {}

interface Bar<F extends Foo<?>> {
    F getFoo();
}

abstract class AbstractBar<F extends AbstractFoo<? extends AbstractBar<F>>> implements Bar<F> {
    private final F foo;

    public AbstractBar(F foo) {
        this.foo = foo;
        // This line should now compile correctly
        this.foo.addBar(this);
    }

    @Override
    public F getFoo() {
        return this.foo;
    }
}

class BarImpl1 extends AbstractBar<FooImpl1> {
    public BarImpl1(FooImpl1 foo) {
        super(foo);
    }
}

class BarImpl2 extends AbstractBar<FooImpl2> {
    public BarImpl2(FooImpl2 foo) {
        super(foo);
    }
}

}

© www.soinside.com 2019 - 2024. All rights reserved.