Does a reference to an instance method of a specific object violate type safety in Java?

Is the concept of a method reference to an instance of a specific object a type safety in Java?

According to

https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

you may have your own ComparisonProvider class that does not implement the Comparator interface and still uses an instance of this class as the second argument to the method

Arrays.sort (T [] a, comparator c)

Of course, the implementation of your ComparisonProvider MUST have a method whose signature exactly matches the Comparator.compare () method, but it's still not an instance of Comparator, is it?

In essence, Java 8 allows us to use class instances as if they were implementing a specific interface, but in fact it is not.

This means that we are losing type safety in Java, right?

+4
source share
3 answers

lambda expressions and a method reference do not have a predefined type, these are poly expressions, as shown here . This means that their type is derived from the context in which they are used.

In your example, both of them will be legal, for example:

 BiFunction<Person, Person, Integer> biFun = myComparisonProvider::compareByName;

 Comparator<Person> comp = myComparisonProvider::compareByName;

But at the same time you cannot:

Arrays.sort(pers, biFun);

When you are actually trying to sort an array as follows:

Arrays.sort(pers, myComparisonProvider::compareByName);

At the bytecode level, which is Comparator:

// InvokeDynamic #0:compare:(LTest$ComparisonProvider;)Ljava/util/Comparator;

Also note that this will be true:

Comparator<Person> comp = myComparisonProvider::compareByName;
System.out.println(comp instanceof Comparator); // true

You can enable the flag: -Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here

and see what this method reference is converted to:

final class Test$$Lambda$1 implements java.util.Comparator

compare ( , ):

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

Java 8 , ,

, , .

- , Java 7 - .

, :

Arrays.sort(someArray, someInstance::someMethod);

Java 7 :

Arrays.sort(someArray, new Comparator<SomeType> () {
                public int compare (SomeType one, SomeTypeTwo) {
                    return someInstance.someMethod(one,two);
                }
            });

(.. ), .

+1

Comparator , , , , , , .

Java 8 . . , Comparator, , ( ), . pre Java 8 , Java 8 ( , ).

So, everything is correct for the type system, provided that the lambdas or references used are of the type of the functional interface method.

+1
source

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


All Articles