Kotlin の SAM 変換

この記事では Kotlin の SAM 変換について説明する。まず、前準備として SAM インタフェースについて触れる。

SAM インタフェースとは Single Abstract Method インタフェースの略称である。つまり、定義する抽象メソッドがひとつのインタフェースを SAM インタフェースと呼ぶ (後述の通り、この定義は厳密ではない)。

JDK に標準で含まれる SAM インタフェースには RunnableComparator がある。

Kotlin における SAM 変換とは、関数リテラルで SAM インタフェースを置き換えることである。とはいえ、言葉だけでは理解しづらいと思うので、Kotlin Koans のスニペットで解説しよう。

次は ArrayListComparator を実装した無名オブジェクトでソートするサンプルである。この無名オブジェクトは compare() を実装している。

同様のことを Kotlin の SAM 変換機能で次のように簡潔に書ける。

Collections.sort() の第二引数は単なる関数リテラルだが、これが SAM インタフェースの実装として扱われる。

補足

Comparator は本当に SAM インタフェースなのだろうか? Oracle のドキュメントによると、このインタフェースには compare()equals() のふたつの抽象メソッドがある。

この疑問が FAQ なのか分からないけれど、「Maurice Naftalin’s Lambda FAQ」には次のような記載がある。

The interface Comparator is functional because although it declares two abstract methods, one of these—equals— has a signature corresponding to a public method in Object. Interfaces always declare abstract methods corresponding to the public methods of Object, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count.

Comparator は functional interface (i.e. SAM interface) である。抽象メソッドがふたつ宣言されているものの、そのうち equals()Object クラスのパブリックメソッドとシグネチャが同じだ。interface は常に Object のパブリックメソッドを暗黙的に宣言している。暗黙的であれ明示的であれ、こういうメソッドは数えあげる対象ではない。

なるほど。

コメントを残す

コメントを投稿するには、以下のいずれかでログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中