[解決済み] Javaにおける「SAM型」とは何ですか?
質問
Java-8の仕様書を読んでいると、「SAM型」という言葉をよく目にします。これが何であるかの明確な説明を見つけることができません。
SAM型とはどのようなもので、どのような場面で使われるのか、例を教えてください。
どのように解決するのですか?
要約すると
Jonが貼ったリンク
1
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
と同じ名前を持たない特定のメソッドを使用しています。
Comparator.compare
そうすれば、メソッドのインターフェイス名に従う必要がなく、1つのクラスで複数の比較オーバーライドを持つことができ、ラムダ式によってその場でコンパレータを作成することができるのです。
もっと深く...
より深いレベルでは、Javaはこれらの実装を
invokedynamic
というバイトコード命令がJava 7で追加されました。先ほど、Lambdaを宣言すると、Lambdaのインスタンスが生成されると言いました。
Callable
または
Comparable
匿名クラスと似ていますが、これは
厳密には
のようになります。その代わり、最初に
invokedynamic
が呼び出されると、Lambda 関数ハンドラを作成します。
LambdaMetafactory.metafactory
メソッド
そして、このキャッシュされたインスタンスを今後のLambdaの呼び出しに使用します。詳しくは
この回答
.
このアプローチは複雑で、スタックメモリーからプリミティブ値や参照を直接読み取ってラムダコードに渡すコードも含まれています(例えば、ラムダコードに渡すために
Object[]
を呼び出すための配列)、バイトコードの互換性を気にすることなく、将来のLambda実装の反復が古い実装を置き換えることを可能にします。Oracle社のエンジニアが新しいバージョンのJVMで基礎となるLambdaの実装を変更した場合、古いJVMでコンパイルされたLambdaは、開発者側で変更することなく自動的に新しい実装を使用することができます。
1 リンク先の構文が古くなっています。リンクの ラムダ式Javaトレイル をクリックすると、現在の構文が表示されます。
関連
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
javax.net.ssl.SSLException: 読み取りエラー: ssl=0xdeae5100: システムコール中の I/O エラー、接続 res
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] リフレクションとは何か、なぜ有用なのか?
-
[解決済み] C#がforeachで変数を再利用するのは理由があるのか?
-
[解決済み】array[idx++]+="a "は、Java 8ではidxを1回増やすが、Java 9と10では2回増やすのはなぜか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
javaで非静的な解を静的な参照にすることができない
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
VMの初期化中にエラーが発生しました java/lang/NoClassDefFoundError: java/lang/Object
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
javaコンパイル時のエラー:不正な文字 '\ufeff' に対する解決策です。
-
が 'X-Frame-Options' を 'deny' に設定しているため、フレーム内にある。
-
javaでよく使われる英単語
-
Maven Pluginの実行がライフサイクル設定の対象外であるエラーの解決
-
[解決済み] Javaで関数をパラメータとして渡すには?[重複しています]。