【问题标题】:Overriding generic getters with proper return type用正确的返回类型覆盖通用 getter
【发布时间】:2015-11-29 19:04:24
【问题描述】:

我在尝试制作小型系统时遇到了 Java 泛型问题。

public void bar(){
    final Shape shape = new Shape();
    final Painter<Shape> shapePainter = shape.getPainter();

    final Circle circle = new Circle();
    final Painter<Circle> circlePainter = circle.getPainter();
}

class Shape {

    public Painter<? extends Shape> getPainter(){
        return new Painter<>(this);
    }

}

class Circle extends Shape {

    @Override
    public Painter<Circle> getPainter(){
        return new CirclePainter(this);
    }

}

class Painter<E extends Shape> {

    public Painter(final E element){
        // ...
    }

    public void paint(final E shape){
        // ...
    }
    
}

class CirclePainter extends Painter<Circle> {

    public CirclePainter(final Circle element){
        super(element);
    }

    @Override
    public void paint(final Circle shape){
        // ...
    }
}

编译失败,第 3 行 (final Painter&lt;Shape&gt; shapePainter = shape.getPainter();) 出现错误:

不兼容的类型:

必需:Bar.Painter

找到:Bar.Painter >

然后可以通过将故障线路更改为:

final Painter<?> shapePainter = shape.getPainter();

但是,后续调用如下:

shapePainter.paint(shape);

会抛出另一个异常:

无法应用 Painter 中的paint (capture)

到(org.example.Bar.Shape)


我觉得我缺少一些可以帮助解决此问题的 Java 泛型的简单部分。我试过摆弄Shape#getPainter 的返回类型,但这通常会在Circle#getPainterbar 中留下编译器错误,似乎没有任何可能的解决方案。

如果使用泛型无法做到这一点,还有哪些其他可用的解决方案?

【问题讨论】:

    标签: java generics inheritance


    【解决方案1】:

    您需要使用 CRTP 使整个类通用化:

    class Shape<T extends Shape<T> {
    
        public Painter<T> getPainter(){
            return new Painter<>(this);
        }
    
    }
    class Painter<E extends Shape<E>> { ... }
    

    【讨论】:

    • 这两个问题都没有解决,现在第 12 行 (return new Painter&lt;&gt;(this);) 上的 this 参数出现类型不兼容的错误。
    • @Obicere:AFAIK,您只能通过使其返回Painter&lt;Shape&lt;T&gt;&gt; 或使用强制转换来解决这个问题。问题是你可以写class Triangle extends Shape&lt;Square&gt;;编译器无法证明thisT
    猜你喜欢
    • 2010-11-06
    • 2017-03-20
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多