JSR 335: Lambda expressions

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の話もあるけど、知りたければラムダの説明を読んでね。

JSR 337: Java SE 8 Release Contents

来年にはリリースされると思われるJava 8だけど、これによって大きく変わると思われるので、時間があるときにでもちょっとずつ押さえていこうと思う。まず、Java 8の中身を決めるJSRはJSR 337になると思われる。まぁ、そこを見れば、Java 8に何が含まれるのかが予想することができるだろう。というわけで、見てみると、以下のものたちが含まれようとしている。

  • JSR 308: Annotations on Java Types
  • JSR 310: Date and Time API
  • JSR TBD: More Small Enhancements to the Java Programming Language (OpenJDK Project Coin)
  • JSR 335: Lambda Expressions for the Java Programming Language (OpenJDK Project Lambda)
  • JSR TBD: Java Platform Module System

これ以外にもJava仕様的なメンテナンスっぽいJSRたちもあるけど、こんなかで把握していく必要があるのはラムダだろうな…。まぁ、順に見ていくのが良いかね。

Stringのformatで改行文字

String#format()もそんなに使うわけじゃないから、

String.format("hoge hoge\n", ...)

という感じのコードを書いていたら、Sonarに指摘された…。改行は\nじゃなくて、%nを使えと言われた。つまり、

String.format("hoge hoge%n", ...)

という感じらしい。これで機種依存の改行コードになるから、こっちを使えということか…。