Using a Type Parameter in a Java Method

In Java Precision 3rd Ed. There is the following code snippet:

BiConsumer<Double[], Comparator<Double>> arraySorter = Arrays::<Double>sort;

However, I noticed that even when I leave <Double>after ::, the method reference is still valid (which makes sense because of type parameters for BiConsumer).

Nevertheless, I am rather confused by whether there are cases when ::<T>it would be necessary in the method reference, and if so, then the example would be very useful.

+4
source share
3 answers

This is type inference in action, in most cases the compiler infers types for you, and therefore means that you do not need to provide them explicitly.

However, there are certain circumstances in which you need to manually specify the types of prompts.

, Java 8 .

, :

BiConsumer<Double[], Comparator<Double>> arraySorter = Arrays::sort;

- .

, , Java-7, Java-8, - :

void exampleMethod(List<Person> people) {
      // do logic
} 

exampleMethod(Collections.emptyList())

:

someMethodName(new HashMap<>());
...
void someMethodName(Map<String, String> values);

.

, - , , - :

...
...
.collect(Collectors.toList());

:

...
...
.collect(Collectors.<Person>toList());

, , , .

+3

, Java 10 (var name = ...;) . , , , (::<T>) .

...

var arraySorter = Arrays::<Double>sort;

... . , , , .


, , , .

class Spy {
    static <T> Function<T,T> f2(Function<T,T> f) {
        return f.andThen(f);
    }

    static <T> T identity(T t) {
        return t;
    }
}

, , :

Function<Double,Double> double_identity = f2(Spy::<Double>identity);

, ::<Double>

Function<Double,Double> double_identity = f2(Spy::identity);

, .

var double_identity = f2(Spy::identity);             // Infers <Object>!
Object obj = null;
double_identity.apply(obj); 

, , .

var double_identity = f2(Spy::<Double>identity);     // Error: Double != Object

, . f2:

var double_identity = Spy.<Double>f2(Spy::identity); // Works.

. . Function<Double,Double> f2(...), . var name = ..., , : Object, Spy.<Object>f2(...), Function<Object,Object>.

, , , , Spy::<Double>identity Spy.<Double>f2(...) Function<Double,Double>. , Java 11? , .

var name = ...;, OP.


@Eugene Java 10.

+3

Java 8 (JEP 101), . Java 8 sort .

JEP 101 , - , ( ). , generic- - , .

:

class Main {

    String s = MyList.nil().head(); // Incompatible types. Required: String. Found: Object.

    static class MyList<E> {
        private E head;
        static <Z> MyList<Z> nil() { return new MyList(); }
        E head() { return head; }
    }
}

nil() String s = MyList.nil().head(). , ,

String s = MyList.<String>nil().head();

MyList<String> ls = MyList.nil();
String s = ls.head();

Note. The example with chained calls does not contain a method reference to a general method (syntax ::<>), as in the original question, but the output method given in both examples is the same. Therefore, the limitations of the output are also the same.

+1
source

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


All Articles