こんにちは。
そんなに雨が好きなわけでもないですが、
こう暑さを実感すると、雨が降っていても涼しい方が幸せな気がします。
水不足ですしね。
さて、タイトルの通りです。
関数インタフェースのラッパーをつくろうかと思ったら、参照があいまいとか怒られてしまったので、
ラムダの型推論がどこまで効くのか確認してみようかと思います。
検証条件は
Java:1.8.0
IDE:NetBeans IDE 8.1
です。
では、早速こんな感じでクラスを作ります。
public class Test { public static void main(String[] args) { Test test = new Test(); // ここに書くよ! } /** * Supplier () -> T */ <T> void method(Supplier<T> s) { } /** * Consumer (T) -> void */ <T> void method(Consumer<T> c) { } /** * Predicate (T) -> boolean */ <T> void method(Predicate<T> p) { } /** * Function (T) -> R */ <T, R> void method(Function<T, R> f) { } /** * UnaryOperator (T) -> T */ <T> void method(UnaryOperator<T> uo) { } /** * BinaryOperator (T, T) -> T */ <T> void method(BinaryOperator<T> bo) { } }
まず1つめ。
引数なしで戻り値を返すSupplierです。
test.method(() -> "a");
これはちゃんと判断できるようです。
OK。
2つめ。
引数を受けて戻り値を返さないConsumerです。
test.method(e -> System.out.println(e));
eの型がなんだかわからないですが、Object#toStringがかかるから大丈夫でしょう。
・・・と思ったらさっそくエラーになってしまいました。
「methodの参照はあいまいです
Testのメソッド
いや、一致しないよ。戻り値ないからUnaryOperatorは無理だよと言いたいところです。
NG。
3つめ。
引数を受けて戻り値にbooleanを返すPredicateです。
test.method(e -> "a".equals(e));
これもエラーです。
「methodの参照はあいまいです
Testのメソッド
あーなるほど、TがBooleanだったらAutoUnBoxingでbooleanで戻せますもんね。
ってことでこうしてみます。
test.<String>method(s -> "a".equals(s));
が、
「methodの参照はあいまいです
Testのメソッド
そういうことじゃないんですね。
せめて今度はFunctionとの区別がつかないよとかならわかりますけども。
NG。
4つめ。
引数と戻り値の型が違うFunctionです。
test.<String, Integer>method(s -> Integer.parseInt(s));
型バインドが効いたようでエラーになりません。
OK。
5つめ。
引数と戻り値の型が同じUnaryOperatorです。
test.<String>method(s -> s);
これは案の定エラーになります。Predicateと一緒ですね。
「methodの参照はあいまいです
Testのメソッド
NG。
最後。
2つ引数を受けて戻り値を返すBinaryOperatorです。(引数1、引数2、戻り値の型はすべて同じ)
test.<String>method((s1, s2) -> s1 + s2);
二つ引数を取るのはこの型だけなので大丈夫です。
OK。
つまり、
①ラムダの引数の数や型は推論に利用される
②ラムダの戻り値の型(voidも含め)は推論に利用されない
ということでいいんでしょうか。
ちょっともやもやしますね。