为什么我使用Java泛型扩展不起作用?

41zrol4v  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(107)

这段代码无法编译,我很难理解为什么:

private final Map<String, ValueWriter<? extends Value>> valueWriters = new HashMap<>();

public void write(CompositeValue value) throws IOException {
    for (Entry<String, ValueWriter<? extends Value>> writer : valueWriters.entrySet()) {
        Value v = value.getValue().get(writer.getKey());
        ValueWriter<? extends Value> valueWriter = writer.getValue();
        valueWriter.write(v);
    }
}

这在valueWriter.write(v)上给出了以下编译错误:

incompatible types: Value cannot be converted to capture#1 of ? extends Value

其中ValueWriter的实现方式如下:

public interface ValueWriter<T extends Value> {
    void write(T value) throws IOException;
    void delete(Key key) throws IOException;
}

基本上,我希望valueWriter接受任何实现Value接口的类。为什么这不起作用,我如何实现它?
最小可重现性示例:

public class Main {
    private ValueWriter<? extends Value> writer;

    public void write(Value v) {
        writer.write(v);
    }
    
    interface Value {
        
    }
    interface ValueWriter<T extends Value> {
        void write(T v);
    }
}
mcvgt66p

mcvgt66p1#

当你写:

ValueWriter<? extends Value> valueWriter = writer.getValue();

valueWriter可以是ValueWriter<A>类型,其中A扩展Value
然后valueWriter.write期望A类型的东西...而你给予v类型Value。编译器不能保证vA类型(取决于实际的valueWriter类型)。
你应该使用如下代码重写程序:

ValueWriter<A> valueWriter = writer.getValue();

其中A扩展了Value,并将A设置为v的类型。A应该由程序在某处引入。

相关问题