J2SE 5で導入されたアノテーションは、Java SE 8で初めて大きな変更が加えられました。その中で最も重要な変更が、型アノテーションの導入です。型アノテーションは、その名の通り型に対するアノテーションです。型アノテーションによって、これまでアノテーションが記述できなかった箇所にアノテーションを記述できるようになるのです。

 今回は、まず型アノテーションが導入された背景について説明し、その後、型アノテーションについて説明を加えます。

アノテーションによる静的コード解析

 アノテーションはコード生成など様々な用途に使用されます。 その用途の1つに制約のチェックがあります。@Overrideアノテーションや@FunctionalInterfaceアノテーションなどが、制約のチェックに使用されるアノテーションです。

 例えば、リスト1のようにFooインタフェースを定義してみましょう。

リスト1●@FunctionalInterfaceによる制約チェックの例

@FunctionalInterface
public interface Foo {
    public void foo();
    public void bar();
}

 Fooインタフェースは文法的には間違いはありません。しかし、@FuncationalInterafceアノテーションを付記していることで、Fooインタフェースが関数型インタフェースであることを示しています。

 関数型インタフェースは実装すべきメソッドが1つであるべきなのですが、Fooインタフェースでは2つのメソッドを定義しています。このため、コンパイルすると、次のようにコンパイルエラーが表示されます。

C:\demo>javac Foo.java
Foo.java:1: エラー: 予期しない@FunctionalInterface注釈
@FunctionalInterface
  Fooは機能インタフェースではありません
    インタフェース Fooで複数のオーバーライドしない抽象メソッドが見つかりました
エラー1個

 関数型インタフェースは実装すべきメソッドを1つしか定義できないという制約を、アノテーションによってチェックできるのです。しかし、この用途でアノテーションが十分活用されているわけではありません。

静的コード解析

 静的コード解析は、実行時ではなく、ソースコードに対して何らかの解析を行うことを示しています。多くの場合、バグの温床となりそうな箇所をチェックする用途に使用されています。

 Javaの静的コード解析の代表的なツールとして、FindBugsPMDなどがあります。

 例えば、リスト2をFindBugsで解析してみましょう。

リスト2●バグの温床となるコードを含んだ例

public class Container<T> {
    private T value;

    public Container(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
    
    @Override
    public boolean equals(Object other) {
        if (other != null && other instanceof Container) {
            return value.equals(((Container) other).value);
        } else {
            return false;
        }
    }
}