Java 8で導入される予定のラムダ式。Javaの世界だと、Java 5 で遭遇した以上の変化が起きるかもしれない。まぁ、仕様としては、JSR 335 みたいだけど、OpenJDKのところにラムダに関する説明もある。これをすごくざっとまとめると、ラムダ式はクロージャーとか匿名メソッドみたいなやつのこと。今まで
button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ui.dazzle(e.getModifiers()); } });
みたいにやっていたかもしれないけど、
button.addActionListener((ActionEvent e) -> {ui.azzle(e.getModifiers()});
みたいなことができるようになる。そんなわけで、
new Thread(() -> { connectToService(); sendNotification(); }).start();
ということも普通に起きる感じ。そんで、興味深いのが Target Typing。上記の例のnew Thread()の引数に与えた()->{…}の型が推論されてRunnableになるっぽい。なので、
Callable c = () -> "done";
とすれば、それはCallableになるし、
Comparator c = (s1, s2) -> s1.compareToIgnoreCase(s2);
とすれば、Comparatorになるようだ。そんでもって、省略とかもありっぽいから、
button.addActionListener(e -> ui.dazzle(e.getModifiers()));
というようにいろいろとなくなる…。そして、以下のような状況で勝手に推論して状況に応じて決まるみたい。
- 変数宣言の型
- 引数の型
- 戻りの型
- 配列のパラメータ型
- メソッドやコンストラクタの引数
- ラムダ式の本文
- ?:の条件式
- キャストの型
まぁ、いろんな状況で型をよろしくやっておくよ、という感じだな。そんで、JavaScriptとかではお馴染みのレキシカルスコープ。
あとは、既存のメソッドとかも渡すことができるみたい。
class Person { private final String name; private final int age; public static int compareByAge(Person a, Person b) { ... } public static int compareByName(Person a, Person b) { ... } } Person[] people = ... Arrays.sort(people, Person::compareByAge);
つまり、::で指定する。上記はstaticなメソッドだけど、インスタンスのメソッドに対してもhoge::doRunみたいなことができるみたい。さらに、コンストラクタもできるみたいで
SocketImplFactory factory = MySocketImpl::new;
という例もある。あとは、defaultの話もあるけど、知りたければラムダの説明を読んでね。