Skip to content

Instantly share code, notes, and snippets.

@Satomaru
Last active February 28, 2017 06:53
Show Gist options
  • Save Satomaru/04056c382c88e2cd72e9 to your computer and use it in GitHub Desktop.
Save Satomaru/04056c382c88e2cd72e9 to your computer and use it in GitHub Desktop.
Java8u74において、型パラメータに&結合を用いた場合、ラムダ式の代わりにメソッド参照を利用すると、LambdaConversionExceptionが発生してしまう問題
package jp.satomaru;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
public class FooBarProcessor {
@RequiredArgsConstructor
public static class Foo {
@Getter public final String value;
}
public interface Bar {
Integer getId();
}
public static class Baz extends Foo implements Bar {
@Getter private final Integer id;
public Baz(Integer id, String value) {
super(value);
this.id = id;
}
}
public static void main(String[] args) {
toIdStreamCaseOk(Stream.of(new Baz(1, "a"), new Baz(2, "b"), new Baz(3, "c")));
toIdStreamCaseNg(Stream.of(new Baz(1, "a"), new Baz(2, "b"), new Baz(3, "c")));
}
public static <T extends Foo & Bar> Stream<Integer> toIdStreamCaseOk(Stream<T> stream) {
// これは実行できる。
return stream.map(t -> t.getId());
}
public static <T extends Foo & Bar> Stream<Integer> toIdStreamCaseNg(Stream<T> stream) {
// これは実行できない。
return stream.map(Bar::getId);
}
}
@Satomaru
Copy link
Author

型パラメータにT extends Foo & Barと宣言されている時、
TのBar実装にアクセスするラムダ式に対して、Barのメソッド参照を利用すると、LambdaConversionExceptionが発生します。
これはおそらく、AbstractValidatingLambdaMetafactory#validateMetafactoryArgsにおいて、
「TはBarではない」と誤認識されているのではないかと推測されます。

なお、Java8u40においては、本現象は起こっていません。

@Satomaru
Copy link
Author

Java8u77でも同じ現象が出ることを確認しました。

@Satomaru
Copy link
Author

Java8u121でも同じ現象が出ますね。もしかして、仕様?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment