我是这堂课:
public abstract class SlightExpression<T> extends Expression<T> {
public BooleanExpression eq(Expression<? super T> right) {}
}
去看下一句话:
SlightExpression<?> left;
SlightExpression<?> right;
//...
left.eq(right);
Java告诉我:
The method eq(capture#19-of ?) in the type SlightExpression<capture#19-of ?>
is not applicable for the arguments (SlightExpression<capture#20-of ?>)
然而,
public abstract class StringExpression extends SlightExpression<String> {}
然后,Java没有告诉我任何事情。
StringExpression s, f;
s.eq(f);
我不明白这种行为。
答案 0 :(得分:3)
当左右声明为
时SlightExpression<?> left;
SlightExpression<?> right;
您可以为它们分配具有不同参数类型的SlightExpression
。例如:
left = new SlightExpression<Integer>();
right = new SlightExpression<String>();
现在,您无法将SlightExpression<String>
传递给eq
实例的SlightExpression<Integer>
方法。
另一方面,在您的第二个片段中,两个实例都是SlightExpression<String>
的子类,因此将一个实例作为参数传递给另一个实例的eq
方法没有问题。
为了更好地理解这个概念,您可以将它应用于更好的已知类。例如:
List<?> l1 = new ArrayList <String> ();
List<?> l2 = new ArrayList <Integer> ();
l1.addAll (l2); // this doesn't pass compilation, since you can't add Integer elements to
// a List<String>
List<?> l1 = new ArrayList <String> ();
List<?> l2 = new ArrayList <String> ();
l1.addAll (l2); // this doesn't pass compilation too, since the compiler doesn't know that
// l1 and l2 will refer to Lists of the same element type when addAll is
// invoked
另一方面,这个片段将通过编译,因为编译器发现两个列表具有相同的元素类型:
List<String> l1 = new ArrayList <String> ();
List<String> l2 = new ArrayList <String> ();
l1.addAll (l2);