【Java進化史 第19回 前編】Java8 〜interfaceが壊れた日(@の正体)〜
若手のコードを見て、固まった。
interface に @ が付いている。
しかも、その中に実装らしきものがある。
例えば、こんなコードだ。
@FunctionalInterface
public interface Task {
void execute();
default void log() {
System.out.println("log");
}
}
@ が付いている。
しかも、実装まである。
え?
interface って、実装書けたっけ?
何が起きているのか、分からなくなった。
■ 混乱は、2つあった
落ち着いて見ると、
混乱は2つあった。
1つ目。
上に付いている「@」。
2つ目。
interface の中にある「実装」。
一気に理解しようとして、止まった。
だから今回は、
まず「@」のほうだけ整理する。
■ @FunctionalInterface が出てきたら
正直、「関数型」という言葉は難しい。
だから私は、こう読むことにした。
「この interface は、メソッドが1つだけです」
それだけだ。
@FunctionalInterface
public interface Converter<T, R> {
R convert(T input);
}
見るべきなのは、ここ。
抽象メソッドが1つだけ。
もし2つに増やすと、
コンパイルエラーになる。
つまりこれは、
「1メソッドで使います」
という宣言だ。
■ なぜ、わざわざ宣言するのか
では、なぜそんな宣言が必要なのか。
理由はシンプルだ。
うっかり2つ目の抽象メソッドを 追加してしまうのを防ぐため。
もし増やせば、コンパイルエラーになる。
つまりこれは、 設計のブレを防ぐための安全装置だ。
特別な機能を追加するものではない。
設計の意図を、はっきりさせるための印だ。
■ interface の形は変わっていない
public interface。
メソッド定義。
書き方は昔と同じだ。
@ が付いただけ。
interface 自体が 別物になったわけではない。
■ もう1つの混乱
だが、まだ疑問は残る。
なぜ interface の中に、 実装があるのか。
それは、@ とは別の進化だ。
Java8は、 interface にもう1つの変化を加えていた。
それが何なのか。
そして、なぜそんな変更が必要だったのか。
次回、整理してみる。