Java generics <? super T>: not applicable methods

I have this class:

public abstract class SlightExpression<T> extends Expression<T> {
    public BooleanExpression eq(Expression<? super T> right) {}
}

Go to the following sentence:

    SlightExpression<?> left;
    SlightExpression<?> right;      
    //...

    left.eq(right);

Java tells me:

The method eq(capture#19-of ?) in the type SlightExpression<capture#19-of ?> 
is not applicable for the arguments (SlightExpression<capture#20-of ?>)

However

public abstract class StringExpression extends SlightExpression<String> {}

Then Java doesn't tell me anything about it.

StringExpression s, f;
s.eq(f);

I do not understand this behavior.

+4
source share
1 answer

If left and right are declared as

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

You can assign them SlightExpressionhaving different types of parameters. For instance:

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

Now you cannot pass SlightExpression<String>to the eqinstance method SlightExpression<Integer>.

On the other hand, in the second fragment, both instances are subclasses SlightExpression<String>, so there is no problem passing one instance as an argument to the method of eqanother instance.

, . :

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

All Articles