SSブログ

ラムダ式(1) [Java 8]

Java 8では、Java言語の仕様が大きく変わります。新たな言語仕様にキャッチアップするために学習を始めたので、メモ程度ですが、分かったことを順不同に今後書いていきたいを思います。したがって、新たな言語仕様のチュートリアルではありませんので注意してください。

ラムダ式は、現在、EarlyAccess版のOpenJDKで使用でき、以下のサイトからダウンロードできます。

http://jdk8.java.net/lambda/

Java 8ではIterableインタフェースにforEach()メソッドが追加されていますので、Iterableインタフェースを実装しているコレクションを使用して、次のようなコードを書くことができます。
import java.util.List;
import java.util.ArrayList;

public class Lambda01 {
    public static void main(String[] args) {
        List<String> messages = new ArrayList<>();

        messages.add("Hello");
        messages.add("World");

        messages.forEach(msg -> System.out.printf("%s ", msg));
        System.out.println();
    }
}
forEach()メソッドには、引数msgを受け取り、それを出力するという簡単なラムダ式が渡されています。コンパイルして実行した結果は、次の通りです。
C:\Users\Yoshiki Shibata\Desktop\java8study>javac Lambda01.java

C:\Users\Yoshiki Shibata\Desktop\java8study>java Lambda01
Hello World
ここで不思議に思うのは、forEach()メソッドの引数の型はIterableインタフェースではどのように定義されているかということです。調べて見ると次のようになっています(コメントは削ってあります)。
package java.lang;

import java.util.Iterator;
import java.util.function.Consumer;

@FunctionalInterface
public interface Iterable {
    Iterator<T> iterator();

    public default void forEach(Consumer<? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}
インタフェースのなのにメソッドの実装が書かれていることは今回は無視して、引数の型はConsumerインタフェース型となっています。Java 6までの言語仕様の知識から、「Consumberインタフェースを実装した無名クラスをコンパイラが生成しているのでは」と単純に推測できます。

しかし、コンパイル結果としては、Lambda01.classファイルしか存在しません。それで、javapで調べると次のような結果となります。
C:\Users\Yoshiki Shibata\Desktop\java8study>javap -p Lambda01
Compiled from "Lambda01.java"
public class Lambda01 {
  public Lambda01();
  public static void main(java.lang.String[]);
  private static void lambda$0(java.lang.String);
}
forEach()メソッドに渡したラムダ式の実体は、どうもこの lambda$0(java.lang.String)のようです。でも、acceptという名前でないし、一体どうやってConsumerインタフェースとして渡されているのかが不思議になります。(続く)
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0