SerializableとCloneableはマーカーインターフェイスの悪い例であることを最初に主張します。もちろん、これらはメソッドとのインターフェースですが、などのメソッドを意味しますwriteObject(ObjectOutputStream)
。(コンパイラーは、writeObject(ObjectOutputStream)
メソッドをオーバーライドしないと、すべてのオブジェクトに既にがあるclone()
場合にclone()
メソッドを作成しますが、コンパイラーは実際のメソッドを作成しますが、警告があります。これらは両方とも、実際にはそうではない奇妙なエッジケースです。良いデザイン例です。)
マーカーインターフェイスは通常、次の2つの目的のいずれかに使用されます。
1)多くのジェネリックで発生する可能性がある、過度に長い型を回避するためのショートカットとして。たとえば、次のメソッドシグネチャがあるとします。
public void doSomething(Foobar<String, Map<String, SomethingElse<Integer, Long>>>) { ... }
入力するのが面倒で面倒であり、さらに重要なことに、理解するのが困難です。代わりにこれを考慮してください:
public interface Widget extends Foobar<String, Map<String, SomethingElse<Integer, Long>>> { }
その後、メソッドは次のようになります。
public void doSomething(Widget widget) { ... }
ウィジェットがより明確になるだけでなく、ウィジェットインターフェースをJavadocできるようになり、ウィジェットのコード内のすべての出現箇所を検索するのも簡単になりました。
2)マーカーインターフェイスは、Javaの交差タイプの欠如を回避する方法としても使用できます。マーカーインターフェイスを使用すると、メソッドシグネチャなど、2つの異なるタイプのものを要求できます。上で説明したように、アプリケーションにインターフェースウィジェットがあるとします。ウィジェットを必要とするメソッドがあり、それをたまたまそれを反復させることができる場合(それは工夫されていますが、ここで私と一緒に動作します)、両方のインターフェイスを拡張するマーカーインターフェイスを作成することが唯一の良い解決策です。
public interface IterableWidget extends Iterable<String>, Widget { }
そしてあなたのコードで:
public void doSomething(IterableWidget widget) {
for (String s : widget) { ... }
}
Serializable
注釈としては意味が@NonNull
なく、インターフェースとしても意味がありません。私は言うでしょう:注釈はマーカー+メタデータです。ところで、Annotationsの前任者は、Javadocで生まれ、Annotationsによって殺されたXDocletでした。