2005 年、Java 5 の登場により、私たちはアノテーションと呼ばれる新しいエンティティを知るようになりました。

注釈は、コード内で宣言できる特別な形式の構文メタデータです。これらは、コンパイル時または実行時にコードを分析するために使用されます。アノテーションは、ラベル、タグ、またはコンパイラ ヒントと考えることができます。

おそらく、これまでに注釈を目にしたことがあるでしょう。たとえば、親クラスのメソッドをオーバーライドする場合は、メソッド自体の前に@Overrideを記述します。このアノテーションは、親のメソッドが子クラスでオーバーライドされることを示します。

構文:

@Override
public int hashCode() {
      return super.hashCode();
}

アノテーションはメソッドだけに適用されるわけではないことにすぐに注意してください。これらは、パッケージ、クラス、メソッド、フィールド、パラメーターとともに使用されます。

注釈がどのように機能するかを理解するために、まずマーカー インターフェイスの概念について理解しましょう。Java の出現以来、開発者は常に、クラスに対して特定のアクションを実行するためにクラスをマークする方法を必要としてきました。

Java 5 より前では、私たちが期待しているインターフェイスとは異なるインターフェイスが使用されていました。それには手段も契約もありませんでした。ある意味、クラスを特別なものとしてマークしただけです。

このようなインターフェースはマーカーインターフェースと呼ばれました。名前から、その目的は JVM、コンパイラ、またはライブラリのクラスをマークすることであると推測されるかもしれません。Serializableなどの一部のマーカー インターフェイスは残ります。このマーカー インターフェイスにより、クラスのインスタンスをシリアル化できることを示すことができます。

これまで見てきたように、マーカー インターフェイスはアノテーションの導入後も存続します。

注釈とマーカーのインターフェイス:

@MyAnnotation
public class MyClass {}
public class MyClass implements MarkerInterface {}

どちらのアプローチも目的は同じですが、実装には明らかな違いがあります。たとえば、クラスが特定の型に属していることを示すインターフェイスとアノテーションについて考えてみましょう。

インターフェイスを使用している場合は、クラスをマークします。使い方を誤ってエラーが発生すると、コンパイル時に問題が発見され、プログラムは実行できなくなります。

アノテーションの場合、すべてはそれほど単純ではありません。ここでは実行時にエラーが検出されます。つまり、プログラムは開始されますが、当然のことながら終了しません。

将来使用するためにクラスをマークする必要がある場合は、そのインスタンスを特定のメソッドに渡す必要があることに注意してください。

public class MyInteger implements Sum {}
interface Sum {};

public static void main(String[] args) throws IOException {
        increase(new MyInteger());
}

public static void increase(Sum count) {
        // TODO
}

ここではマーカー インターフェイスが最適に機能します。

アノテーションがサポートするパラメータなど、さらに何かが必要な場合は、アノテーションを使用するのが最善です。

JDK の標準のアノテーションを見てみましょう。

注釈 説明
@オーバーライド メソッドがスーパークラスのメソッドをオーバーライドするか、抽象クラスまたはインターフェイスのメソッドを実装することを指定します。
@Override
public int hashCode() {
        return super.hashCode();
}
@非推奨 コードを非推奨としてマークします。
@Deprecated
public abstract void method();
@SuppressWarning アノテーションが付けられた要素に対するコンパイラ警告を無効にします。複数のカテゴリの警告を無効にする必要がある場合は、 @SuppressWarnings({"unchecked", "cast"}) のように中括弧で囲む必要があることに注意してください。
public class DocumentsFolder {
   private List documents;

   @SuppressWarnings("unchecked")
public void addDocument(String document) {
            documents.add(document);
   }
}

この例では、定義された型 (ジェネリック型) を持たないリストに追加しようとしています。コンパイラはこれについて警告します。これは非常に便利ですが、場合によっては「警告」が多すぎてうるさくなることがあります。このメソッドのアノテーションを使用して、コンパイラ警告の種類を引数として指定できます。マーカーはたくさんあるので、すべてを覚えておく必要はありません。通常、IDEA がどれを追加すればよいかを教えてくれます。

複数の引数を使用した別の例:

@SuppressWarnings({"unchecked", "deprecated"})