Issue with Comparator.comparing
B. Blaser
bsrbnd at gmail.com
Mon Dec 17 12:36:20 UTC 2018
On Fri, 14 Dec 2018 at 16:28, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
>
> I get that there are other ways to make the example working. But the API says:
>
> "Accepts a function that extracts a Comparable sort key from a type T, and returns a Comparator<T> that compares by that sort key."
>
> There's no other note in the API which hints at the fact that it might spectacularly fail because of heap pollution. And the fact that it is a synthetic cast that is failing, is strongly hinting at something at odds with the type-system.
>
> Maurizio
I agree there's something odd, but I really believe this isn't when
capturing the receiver which still ends up with a type variable (JLS
§5.1.10), the key extractor remaining generic and not instantiated.
As I said previously, the issue might be in the following expression:
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
in 'Comparator::comparing':
http://hg.openjdk.java.net/jdk/jdk/file/dcbb71b9e7c0/src/java.base/share/classes/java/util/Comparator.java#l469
which is where 'keyExtractor' is "instantiated" to the type of c1 and
c2 which is assumed to be the same, 'T' in this case:
http://hg.openjdk.java.net/jdk/jdk/file/dcbb71b9e7c0/src/java.base/share/classes/java/util/Comparator.java#l468
I don't think there's any type system issue here, the API simply
requires all elements to be of the same type 'T' and thus returning
keys comparable between themselves (U extends Comparable<? super U>):
http://hg.openjdk.java.net/jdk/jdk/file/dcbb71b9e7c0/src/java.base/share/classes/java/util/Comparator.java#l465
This assertion being wrong in your example as 'T = ? super Foo<?>' and
keys aren't always comparable between themselves.
The doc should simply says something like here under.
What do you think?
Bernard
diff --git a/src/java.base/share/classes/java/util/Comparator.java
b/src/java.base/share/classes/java/util/Comparator.java
--- a/src/java.base/share/classes/java/util/Comparator.java
+++ b/src/java.base/share/classes/java/util/Comparator.java
@@ -459,6 +459,7 @@
* Comparable} sort key
* @return a comparator that compares by an extracted key
* @throws NullPointerException if the argument is null
+ * @throws ClassCastException if sort keys aren't comparable
between themselves
* @since 1.8
*/
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
More information about the compiler-dev
mailing list