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");