質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

1404閲覧

FunctionInterfaceアノテーションがついていないインターフェースにラムダ渡す派?

root_jp

総合スコア4666

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

0クリップ

投稿2016/12/28 12:30

例えば、java.awt.event.ActionListener のような、抽象メソッドが1つのみのInterafaceは
FunctionInterfaceの条件を満たしているため、ラムダを使うことができますが、
将来的に抽象メソッドが追加された場合、ラムダの部分がコンパイルエラーになると思います。

FunctionInterfaceアノテーションがついていない場合、追加されても文句が言えないため、
ラムダを使わない方が無難でしょうか?
みなさんの考えを教えてください。

amadablam👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

StackOverFlowに同様の質問と詳しい回答があります。
この回答にあるように、FunctionalInterfaceアノテーションが意図的に付けられていないインターフェイスにはライブラリの設計あるいはメンテナンス上の理由が存在する可能性があると思われます。
ComparableやAutoClosable、Iterableインターフェイスなどがわかりやすい例として挙げられていますね。
したがって、抽象メソッドを追加した場合は単にアノテーションを消せばよいとか、ラムダ式で使用しても別に構わないというのではなく、ラムダ式を使用する場合にはそのインターフェイスの設計上の意図を考えるのは重要ではないでしょうか。
ただ、この回答者も言っているようにイベントのリスナー・インターフェイスになぜFunctionalInterfaceアノテーションが付けられていないのかは不明で、むしろラムダ式での実装のいい候補となると言っていますが。
もっとも現状ではFunctionalInterfaceアノテーションの有無にかかわらず、抽象メソッドが1つであればラムダ式を書けてしまうので、ちょっと仕様が中途半端な感がありますね。

投稿2016/12/28 13:03

編集2016/12/28 13:07
amadablam

総合スコア402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

root_jp

2016/12/28 14:40

すごくど真ん中の記事ありがとうございます。見つけれませんでした。。。 回答者の方で、 「インターフェースに抽象メソッドを追加することは、破壊的なことなので。 これを行う予定がありかどうかは疑問です。」 というような回答もあり、確かにその通りだとも思いました。 安易に抽象メソッドを追加してしまうと、バージョンの互換性が一気になくなってしまいますね。 それはインターフェース利用時が、ラムダだろうが匿名クラスだろうが同じことだという swordoneさんの回答でも気付かされました。
guest

0

ベストアンサー

FunctionInterfaceアノテーションは、オーバーライド時のOverrideアノテーションと同様、コンパイラがそのアノテーションの条件を満たすことを保証しているにすぎません。
仮に抽象メソッドが追加されたとしたら、そのアノテーションを消すだけでコンパイルが通ります。それにラムダでなく匿名クラスとして渡したとしてもエラーになります。
結局、ラムダであろうがなかろうが同じことになるので、ラムダでも別に問題ないかと思います。

投稿2016/12/28 12:40

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

root_jp

2016/12/28 14:31 編集

1つの抽象メソッドしか持たないインターフェースに 別の名前の同一シグネチャのメソッドが追加されたら、コンパイルエラーになりますよね。 匿名クラスでは、全ての抽象メソッドの実装が強要されるため、このようなことは起きません。 FunctionInterfaceアノテーションを消すだけでコンパイルが通るのは インターフェース側であって、参照している側がラムダの場合 そちらがコンパイルエラーになってしまいます。
root_jp

2016/12/28 14:33

おっと、失礼しました。上記コメントを訂正させていただきます。 匿名クラスでも、抽象メソッドが追加されてしまったら、そのメソッドの実装が強要されるため、 たしかにコンパイルエラーになりますね。 すごく納得する回答でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問