Does the notion of a reference to an instance method of a particular object break the type-safety in Java?
According to
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
you can have a custom class ComparisonProvider that DOES not implement the Comparator interface, and still use an instance of this class as the second argument of the method
Arrays.sort(T[] a, Comparator c)
Sure, the implementation of your ComparisonProvider MUST have a method whose signature exactly matches the Comparator.compare() method, but that is still not an instance of Comparator, isn't it?
In essence, Java 8 allows us to use instances of classes as if they were implementing a particular interface, while actually they are not.
This means, that we are loosing Type-safety in Java, do we?
lambda expressions and method reference don't have a predefined type, they are poly expressions, as seen here. That means that their type is derived from the context in which they are used.
In your example these both would be legal for example:
BiFunction<Person, Person, Integer> biFun = myComparisonProvider::compareByName;
Comparator<Person> comp = myComparisonProvider::compareByName;
But at the same time you can't do:
Arrays.sort(pers, biFun);
When you actually try to sort the array like this:
Arrays.sort(pers, myComparisonProvider::compareByName);
At the bytecode level that is a Comparator
:
// InvokeDynamic #0:compare:(LTest$ComparisonProvider;)Ljava/util/Comparator;
Also notice that this would print true:
Comparator<Person> comp = myComparisonProvider::compareByName;
System.out.println(comp instanceof Comparator); // true
You can enable a flag : -Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here
and look at what that method reference is transformed into:
final class Test$$Lambda$1 implements java.util.Comparator
and inside it there's the compare
method implementation(I've simplified it and removed some of it's code to make it a little more obvious):
public int compare(java.lang.Object, java.lang.Object);
Code:
4: aload_1
5: checkcast // class Test3$Person
8: aload_2
9: checkcast // class Test$Person
12: invokevirtual Test$ComparisonProvider.compareByName:(Test$Person;Test$Person;)I
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With