我上了这个课:
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);
我不了解这种行为。
最佳答案
当左右声明为
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具有相同的元素类型:
List<String> l1 = new ArrayList <String> ();
List<String> l2 = new ArrayList <String> ();
l1.addAll (l2);