2013-07-28 12 views
72

Java-8仕様を読んで、私は 'SAMの種類'への参照を見ています。私はこれが何であるかについて明確な説明を見つけることができませんでした。Javaの「SAMタイプ」とは何ですか?

SAMタイプとは何か、使用する場合のシナリオ例は何ですか? the link Jon postedを要約する

+4

http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.htmlを参照してください(私は単一の検索の後に見つけました。 –

+0

これは私が必要としていたものです。ありがとう!好奇心のために、あなたはどのキーワードをあなたの検索に使用しましたか? – Cody

+2

人々に古くなった情報を紹介しないでください。もう少し長く検索すると、最新バージョンのhttp://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.htmlにアクセスすることができました。それ自体は18カ月です。現在は多くの場所で古くなっています。OPの質問はhttp://www.lambdafaq.org/what-is-functional-interface/で答えることができます。私は最近、急速に変化する言語とAPIの開発。 –

答えて

79

それが今までダウンした場合など、「SAM」は「単一抽象メソッド」の略で、「SAM-タイプが」Runnableのようなインターフェースを指し、Callableラムダ式は、Javaの8の新機能SAM型とみなされ、自由に変換することができます。例えば

、このようなインターフェイスで:

public interface Callable<T> { 
    public T call(); 
} 

あなたはこのようなラムダ式を使用してCallableを宣言することができます。このコンテキストで

Callable<String> strCallable =() -> "Hello world!"; 
System.out.println(strCallable.call()); // prints "Hello world!" 

ラムダ式は、主にだけ糖衣構文です。それらは匿名クラスよりもコード内で見栄えが良く、メソッドの命名にはあまり制限がありません。リンクから、この例を見てみましょう:

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); 

これはComparator.compareと同じ名前を共有していない具体的な方法、あなたはメソッドのインタフェース命名に従う必要はありません、あなたができる方法を使用してComparatorを作成しますクラス内で複数の比較オーバーライドを行い、ラムダ式を使用してコンパイラをオンザフライで作成します。より深い行く

...より深いレベルで

は、Javaはこれらは私が言ったのJava 7に追加invokedynamicバイトコード命令を使用して実装して、以前のラムダを宣言することにCallableまたは類似Comparableのインスタンスを作成していること匿名クラスですが、それはではなく、厳密にはです。代わりに、invokedynamicが初めて呼び出されたときに、LambdaMetafactory.metafactory methodを使用してLambda関数ハンドラを作成し、その後このLambdaの呼び出しでこのキャッシュされたインスタンスを使用します。詳細はthis answerにあります。

このアプローチは複雑で、プリミティブな値と参照をスタックメモリから直接読み込んでラムダコードに渡すコードも含まれています(たとえば、ラムダを呼び出すためにObject[]配列を割り当てる必要がなくなります)が、バイトコードの互換性を気にすることなく、古い実装を置き換えるラムダ実装の反復。 Oracleのエンジニアが新しいバージョンのJVMで基本となるLambda実装を変更した場合、古いJVMでコンパイルされたLambdasは新しい実装を使用します。


サイドノートとして、リンクの構文が最新ではありません。現在の構文を見るにはLambda Expressions Java Trailを見てください。

+0

あなたは '#{" Hello world! " }; '正しい構文ですか?私は '() - >" Hello world! "のようなラムダ式で表現すると思った。 – asgs

+0

ああ、そうです。私は@Mauriceのコメントを読んだだけです。この投稿を編集して最新の情報を反映させる必要があります。しかし、 '#{}'はLambdasがどのように以前に表現されたのか知っていて良かったです。 – asgs

+1

@asgs Javaトレイルを指し示す一番下のほうに少し先がありましたが、私は先に進み、とにかく現在の構文を使用するために答えを更新しました。 – Brian

関連する問題