Java泛型<! - ?超级T - >:不适用的方法

时间:2016-05-05 07:02:25

标签: java generics

我是这堂课:

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);

我不明白这种行为。

1 个答案:

答案 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);