以下Class A
有什么问题不允许编译?
public class GenericsHell {
interface Shape{}
interface Circle extends Shape {}
interface ShapeHelper<T extends Shape> {
void draw(T shape);
}
class A<T extends Shape> {
A(T shape, ShapeHelper<? extends Shape> helper) {
helper.draw(shape); // Issues not-applicable argument error
}
}
class B {
B(Circle circle, ShapeHelper<Circle> helper) {
helper.draw(circle);
}
}
}
Eclipse出现以下错误:
The method draw(capture#1-of ? extends Shape) in the type ShapeHelper<capture#1-of ? extends Shape> is not applicable for the arguments (T)
答案 0 :(得分:3)
您已将A类的通用参数定义为一件事,但之后尝试在构造函数中以不兼容的方式使用它(<T extends Shape>
与<? extends Shape>
不同。获取代码编译将其更改为始终使用已定义的泛型参数:
class A<T extends Shape> {
public A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
顺便说一句,您的代码不会生成您在问题中显示的错误消息。相反,它会更像是这样:
方法绘制(捕获#1-of?extends GenericsHell.Shape)在类型中 GenericsHell.ShapeHelper是 不适用于参数(T)
答案 1 :(得分:2)
方法draw(捕获#1-of?extends GenericsHell.Shape)类型为GenericsHell.ShapeHelper&lt; capture#1-of?扩展GenericsHell.Shape&gt;不适用于参数(T)
问题在于,在声明中,shape的类型为T,但是您要求的ShapeHelper类型为&lt;?扩展形状&gt;这意味着可以将一个ShapeHelper作为参数传递,其中S和T是不同的。
然后,您可以致电helper<S>.draw(shape<T>);
,这是没有意义的。
此方法的正确实现是:
class A<T extends Shape> {
A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
确保形状和形状辅助器具有兼容类型。
答案 2 :(得分:1)
看到您对A
的来电非常重要。但似乎你做了像A<Integer>
这样的事情。但T
必须根据您的班级声明延长Shape
,而Integer
则不然。因此,要么将<? extends Shape>
更改为<T>
,要么提供Shape
到A
的类型
答案 3 :(得分:0)
请改为尝试:
class A<T extends Shape> {
A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
答案 4 :(得分:0)
记住PECS(制作人extends
,消费者super
)。
helper
是一个消费者(你传递了一些东西),因此它不能是extends
。也许它可能是super
,但我不知道在这种情况下这是否有意义