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