在尝试创建一个小型系统时,我遇到了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<Shape> shapePainter = shape.getPainter();
)上的错误表示:
不兼容的类型:
必需:Bar.Painter&lt; org.example.Bar.Shape&GT;
发现:Bar.Painter&lt;捕获&LT; ?扩展org.example.Bar.Shape&gt;&gt;
然后可以通过将故障线路更改为:
来解决此问题final Painter<?> shapePainter = shape.getPainter();
然而,后来的电话如下:
shapePainter.paint(shape);
将抛出另一个例外:
无法应用Painter中的paint(capture&lt;?extends org.example.Bar.Shape&gt;)
to(org.example.Bar.Shape)
我觉得我错过了一些简单的Java泛型,可以帮助解决这个问题。我试图摆弄Shape#getPainter
的返回类型,但这通常会导致Circle#getPainter
或bar
中的编译器错误似乎没有任何可能的解决方案。
如果泛型无法做到这一点,还有哪些其他解决方案可用?
答案 0 :(得分:0)
您需要使用CRTP:
使整个类具有通用性class Shape<T extends Shape<T> {
public Painter<T> getPainter(){
return new Painter<>(this);
}
}
class Painter<E extends Shape<E>> { ... }