Why can't we capture wildcards for a method with two parameters?

Related to this issue.

I know about holding wildcards. For example, to modify the list, you can use the following:

public static void reverse(List<?> list) { rev(list); } //capturing the wildcard private static <T> void rev(List<T> list) { List<T> tmp = new ArrayList<T>(list); for (int i = 0; i < list.size(); i++) { list.set(i, tmp.get(list.size()-i-1)); } } 

Now I'm trying to write the same thing for a situation like this:

 private int compare (Comparable<?> upper, Comparable<?> lower){ return comp(upper, lower); //The method comp(Comparable<T>, Comparable<T>) is not applicable for the arguments (Comparable<capture#5-of ?>, Comparable<capture#6-of ?>) } private <T> int comp(Comparable<T> upper, Comparable<T> lower){ return upper.compareTo((T) lower); } 

I expected it to be arranged too. Is it possible to capture wildacrds for methods with two or more parameters this way?

+6
source share
2 answers

In this method

 private <T> int comp(Comparable<T> upper, Comparable<T> lower){ return upper.compareTo((T) lower); } 

both parameters have the same type parameter.

Meanwhile, this does not apply to another method:

 private int compare (Comparable<?> upper, Comparable<?> lower){ return comp(upper, lower); } 

Here, the compiler has no evidence that the type parameters for upper and lower same, and why they refuse to give the green light for compilation.

If you want both methods to share the same type parameter, you can make a type parameter with a class . For instance:

 public class YourClass<T> { private int comp(Comparable<T> upper, Comparable<T> lower){ return upper.compareTo((T) lower); } private int compare (Comparable<T> upper, Comparable<T> lower){ return comp(upper, lower); } } 

Another option (if you don't like the first one) is to enter the same upper bound for the type parameters for comp() and compare() . For instance:

 private <T extends SomeSuperClass> int comp(Comparable<T> upper, Comparable<T> lower){ return upper.compareTo((T) lower); } private <T extends SomeSuperClass> int compare (Comparable<T> upper, Comparable<T> lower){ return comp(upper, lower); } 

Alternatively, if you want to avoid casting in the comp() method, you can do:

 public class YourClass<T extends SomeSuperClass & Comparable<T>> { private int comp(T upper, T lower){ return upper.compareTo(lower); } private int compare (T upper, T lower){ return comp(upper, lower); } } 
+2
source

Because, as I said in my answer to your other question, the compiler cannot know what the two are ? denote the same type.

Two ? for each there is an unknown type. The compare method requires two Comparable for the same type T If you call compare from the comp method, the compiler cannot be sure what the two are ? denote the same type.

+4
source

Source: https://habr.com/ru/post/988695/


All Articles