Java >> Java tutorial >  >> Tag >> return

Hvorfor er lambda returtype ikke kontrolleret på kompileringstidspunktet?

I det første eksempel MyInterface::getLength og "I am NOT an Integer" hjalp med at løse de generiske parametre T og R til MyInterface og Serializable & Comparable<? extends Serializable & Comparable<?>> henholdsvis.

// it compiles since String is a Serializable
Function<MyInterface, Serializable> function = MyInterface::getLength;
Builder.of(MyInterface.class).with(function, "I am NOT an Integer");

MyInterface::getLength er ikke altid en Function<MyInterface, Integer> medmindre du udtrykkeligt siger det, hvilket ville føre til en kompileringsfejl, som det andet eksempel viste.

// it doesn't compile since String isn't an Integer
Function<MyInterface, Integer> function = MyInterface::getLength;
Builder.of(MyInterface.class).with(function, "I am NOT an Integer");

Det er fordi din generiske typeparameter R kan udledes at være Objekt, dvs. følgende kompileringer:

Builder.of(MyInterface.class).with((Function<MyInterface, Object>) MyInterface::getLength, "I am NOT an Integer");

Det er den type slutning, der spiller sin rolle her. Overvej den generiske R i metodesignaturen:

<R> Builder<T> with(Function<T, R> getter, R returnValue)

I tilfældet som anført:

Builder.of(MyInterface.class).with(MyInterface::getLength, "I am NOT an Integer");

typen R udledes med succes som

Serializable, Comparable<? extends Serializable & Comparable<?>>

og en String betyder af denne type, derfor lykkes kompileringen.

For eksplicit at angive typen R og find ud af inkompatibiliteten, kan man blot ændre kodelinjen som :

Builder.of(MyInterface.class).<Integer>with(MyInterface::getLength, "not valid");

Java tag