2016-05-05 26 views
4

我有這個類:Java泛型<? super T>:不適用方法

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

當聲明「SlightExpression 左」你需要在上面的聲明中傳入Type。 「」意味着你不知道它會是什麼。 –

回答

3

時左右被宣佈爲

SlightExpression<?> left; 
SlightExpression<?> right; 

您可以分配給他們SlightExpression小號有不同的參數類型。例如:

left = new SlightExpression<Integer>(); 
right = new SlightExpression<String>(); 

現在,你可以不通過SlightExpression<String>SlightExpression<Integer>實例的eq方法。

另一方面,在你的第二個片段中,兩個實例都是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); 
+0

你偷了我的節目:) –