Weźmy taki kod https://ideone.com/ubV2P5 :
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.function.Supplier;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
bar(Ideone::foo, 1.5);
}
static String foo(){
return "Foo";
}
static <T> void bar(Supplier<T> lambda, T value){
}
}
To co mi się nie podoba w tym kodzie, to fakt, że kompiluje się on bez problemów, chociaż wygląda tak, jakbym do metody bar
przekazywał lambdę zwracającą stringa oraz double'a. O ile dobrze rozumiem, wynika to z kowariancji typu zwracanego, przez co przekazując referencję do metody foo
kompilator może to sobie potraktować jako lambdę zwracającą Object
i wtedy double nie powoduje błędu. Szerszy opis można znaleźć w punkcie 9. w http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
Pytanie brzmi: czy jest jakikolwiek sposób na zablokowanie tego? Chciałbym, żeby kompilator krzyknął, że przekazuję double'a jako drugi parametr, a idealnie powinien tam być string. Sygnatura metody bar
może się zmienić, bardziej zależy mi na zachowaniu wywołania w postaci bar(Ideone::foo, 1.5);
, ale nie jest to absolutnie niezbędne, przy czym nie chcę jawnie specyfikować typu parametru, więc coś w stylu Ideone.<String>bar(Ideone::foo, 1.5);
odpada.