本日はJJUG主催のナイトセミナー「Inside Lambda」が開催されました。
http://kokucheese.com/event/index/101955/
内容は2部構成で、目玉はJavaのラムダ式が裏でinvokedynamicを使っている件について「ラムダとinvokedynamicの蜜月」の題名で宮川拓さんの講演、そしてその前の時間にラムダ理解の導入として「Project Lambdaの基礎」の題名で櫻庭祐一さんの講演がありました。
「Project Lambdaの基礎」
http://www.slideshare.net/skrb/project-lambda-24531410
プレゼンテーションのフォントが独特でした。
λ計算のアロンゾ・チャーチさんの写真をあんなに長くひっぱるプレゼンって・・・
Javaのラムダ式は、実装すべきメソッドが1つであるFunctional Interfaceの無名クラスの記述とインスタンシエーションの簡易記法を提供し、ボイラープレートな実装を排除することとのことです。
(引数)-> { 式 }
が基本のラムダ式です。また、条件が合致すれば丸括弧や波括弧が省略できるようです。
- 波括弧とreturnを省略できるのは式が1つのときだけ
- 引数が1つのとき丸括弧省略可能
Javaのラムダ式で注意すべき(よく陥りがちな)問題は次です。
- アンダーバーだけの変数名はNG
- 実質ファイナル
- 無名クラスでのthisとラムダ式でのthisは違う
IntelliJ IDEAとNetBeans(バージョン7.4)は、無名クラスを書くとラムダ式に置き換えるか聞いてくるそうです。
「ラムダとinvokedynamicの蜜月」
http://www.slideshare.net/miyakawataku/lambda-meets-invokedynamic
ラムダ式を含むクラスをコンパイルしても無名クラスのようにクラス名$1.classのようなファイルはできません。ラムダ式の結果にgetClass()すると、クラス名$$Lambda$1 のように表現されています。
ラムダのクラスは、実行時に(ラムダ式を最初に実行した時点で)生成されます。バイトコード(JDK付録のjavapコマンド)では、ラムダ式を記述したクラスには、
private static int lambda$0(int a, int b)
のようなメソッドが生成され、ラムダ式の中身が記述されます。
ラムダ式の実行(メソッド呼び出し)はinvokedynamic命令が使われます。
ここから、CallSite、ブートストラップメソッド、メソッドハンドルといった説明が続きます。(略)
ラムダの直列化(Serializable)には、writeReplace、readResolveが使われています。
参考文献
紹介のあったGoetz氏の資料はより新しいものが次になります。
http://www.slideshare.net/jaxlondon2012/lambda-a-peek-under-the-hood-brian-goetz
メモ
invokedynamicは難しいですね。でも、説明を聞く機会があるたびにすこしずつ理解できるところが増えてきたかなと思います。