モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

Java アノテーションに関する基本知識

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2017/05/13
最終更新最終更新
2019/09/17
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    Javaちょっとできるプログラマ。教育業界のエンジニアです。

    0
    ステッカーを贈るとは?

    Java SE 5 から導入されたアノテーション機能に関する基本事項をまとめます。アノテーションは @Xxx の形式で、Java の言語機能としては表現できない補足情報を注釈 (annotation) として記述するための仕組みです。クラス、インターフェース、メソッド、メンバ変数、メソッド引数などの定義箇所に記述します。

    アノテーションの作成

    アノテーションを利用する場面としては、自分で定義することは少なく、主に Java 言語側が定義する、@Override, @Deprecated, @SuppressWarnings といった標準アノテーションや、フレームワークや外部ライブラリが定義するアノテーションを利用することの方が多いかもしれません。外部で定義されたアノテーションを利用する際の理解を深める目的で、簡単なアノテーションを自分で定義してみます。

    アノテーションの種類

    アノテーションは用途によって 2 種類存在します。

    • マーカーアノテーション → データを持たせることができず、何らかの用途でマークするために利用
    • 単一値アノテーション、フルアノテーション → データを持たせることができるアノテーション

    マーカーアノテーション

    以下のようなファイルを用意します。Eclipse の場合は右クリック → New → Annotation で追加できます。@interface を記述することでアノテーションを定義できます。アノテーション定義のために、アノテーションを利用していることになります。このような、アノテーションを定義するときに付与するアノテーションを特にメタアノテーションとよびます。

    MyAnnotation.java

    package myproject;
    
    public @interface MyAnnotation {
    }
    

    定義したアノテーションは、クラス、インターフェース、メソッド、メンバ変数、メソッド引数などの定義箇所に記述して利用します。利用箇所を制限するためには、アノテーション定義時に @Target メタアノテーションを記載します。以下のように ElementType.METHOD を利用すると、メソッド定義箇所だけで使用できるアノテーションが定義できます。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    }
    

    利用例

    @MyAnnotation
    public void MyMethod() {
    }
    

    メタアノテーションについて

    前述の @Target や後述の @Retention の他に、継承関係にある二つのクラスがあるとき、親クラスに付与すると自動的に子クラスにも付与されたような状況になるアノテーションを定義するための @Inherited があります。クラスのアノテーションにだけ使用できます

    付与されたクラスの javadoc 生成時に、アノテーションで補足した情報をクラスのドキュメントに含めるかどうかを制御する @Documented メタアノテーションもよく使用されます。

    単一値アノテーション

    以下のように String value() を記述すると、値を一つだけ保持できるアノテーションを定義できます。後述のフルアノテーションと似ていますが、value は特別な意味を有するということになります。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    String value();
    }
    

    利用例

    @MyAnnotation("my setting")
    public void MyMethod() {
    }
    

    保持する値を制限したい場合は enum を利用します。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    enum MyEnum {
    val1,
    val2
    }
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    MyEnum value();
    }
    

    利用例

    @MyAnnotation(MyEnum.val1)
    public void MyMethod() {
    }
    

    フルアノテーションではないですが、単一の配列を保持できるようにすることで、複数の値を保持する単一アノテーションを定義できます。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    String[] value();
    }
    

    利用例1

    @MyAnnotation({"str1", "str2"})
    public void MyMethod() {
    }
    

    利用例2

    @MyAnnotation("str1")
    public void MyMethod() {
    }
    

    アノテーションには既定値を定義できます。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    String value() default "my default";
    }
    

    利用例

    @MyAnnotation
    public void MyMethod() {
    }
    

    フルアノテーション

    value ではなく他の名前を使用して、複数の値を保持できるアノテーションを定義できます。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    public @interface MyAnnotation {
    String myattr1();
    int myattr2();
    }
    

    利用例

    @MyAnnotation(myattr1 = "string", myattr2 = 123)
    public void MyMethod() {
    }
    

    Retention 保持期間

    既定では、アノテーションを付与して定義されたクラスやメソッドをコンパイルすると、アノテーション注釈で補足した情報はコンパイル結果に含まれますが、実行時には JVM から読み込まれません。これを変更するためには、アノテーション定義時に @Retention メタアノテーションを利用します。コンパイルすると情報が消失する SOURCE や、コンパイル結果に含まれるだけでなく JVM で実行するときにも読み込まれる RUNTIME が指定できます。

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    //@Retention(RetentionPolicy.CLASS) // 既定値
    //@Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    }
    

    特に @Retention(RetentionPolicy.RUNTIME) を指定した場合は以下のように実行時に利用できます。クラスの構造を実行中に読み取る「リフレクション」を利用します。

    Main.java

    package myproject;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    
    public class Main {
    
        public static void main(String[] args) {
            Class<Main> clazz = Main.class;
    
            try {
                Method method = clazz.getMethod("MyMethod");
    
                // 一覧を取得
                for(Annotation annotation : method.getDeclaredAnnotations()) {
                    System.out.println(annotation);
                }
    
                // 引数で指定して取得
                MyAnnotation annotation = method.getDeclaredAnnotation(MyAnnotation.class);
                System.out.println(annotation);
                if(annotation.value() == 123) {
                    System.out.println("do something...");
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
    
        @MyAnnotation(123)
        public void MyMethod() {
        }
    }
    

    MyAnnotation.java

    package myproject;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
        int value();
    }
    

    実行例

    @myproject.MyAnnotation(value=123)
    @myproject.MyAnnotation(value=123)
    do something...
    

    標準アノテーションについて

    標準アノテーションは多数提供されています。その中でも特に、以下のような標準アノテーションがよく使用されます。

    • @Override 親クラスのメソッドを上書きしていることを明記することで、視認性がよくなるだけでなく、タイプミス等で親クラスに存在しないメソッドを新規作成した際にエラーを発生させます。
    • @Deprecated 非推奨メソッドであることを明記することで、使用するとコンパイル時に警告が出るようになります。
    • @SuppressWarnings 単一値アノテーションです。引数に指定した警告について、アノテーションを付与した箇所で発生するコンパイル時の警告がログに出力されなくなります。@Deprecated メソッドを使用している場合など、警告されていることは把握済みであっても解消することが難しい場合で、コンパイルログの視認性をよくしたい場合などに利用します。@SuppressWarnings("deprecation")@SuppressWarnings("unused") 等のように使用します。

    javadoc におけるアノテーション

    javadoc におけるアノテーションは多数提供されています。その中でも特に、以下のようなアノテーションがよく使用されます。Eclipse の場合は File → Export → Java → Javadoc → Next → Finish で生成できます。

    /**
     * サンプルコメント
     * @author 氏名
     * @param myarg1 引数1 の説明
     * @param myarg2 引数2 の説明
     * @return 返り値の説明
     * @exception IOException メソッド内で発生する例外の説明
     * @version メソッドやクラスのバージョン
     * @see Main#MyMethod(int, int) 関連箇所の説明
     */
    @Deprecated
    @MyAnnotation(123)
    public int MyMethod(int myarg1, int myarg2) throws IOException {
        return 123;
    }
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    Javaちょっとできるプログラマ。教育業界のエンジニアです。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事

      • Spring Security フォームログインのサンプルコード
        Spring フレームワークによる Web アプリケーション開発で、ログイン処理を実装する際は Spring Security が便利です。ここでは特に Spring Boot で Web アプリケーションを開発する場合を対象とし、フォームによる ID/Password ログインを行うためのサンプルコードをまとめます。 公式ドキュメント [Spring Security チュートリアル](http...
        えびちゃんえびちゃん12/4/2019に更新
        いいねアイコン画像0
      • Java配列の宣言方法 (C/C++との違い)
        Javaの配列 Javaの配列宣言方法はC/C++と似ているようで若干異なる。 初期化しない場合 C/C++の int array[10]; はJavaでは int array[] = new int[10]; となる。同様にC/C++の int array[3][3]; はJavaでは int array[][] = new int[3][3]; となる。 初期化
        てんとうむしてんとうむし5/13/2018に更新
        いいねアイコン画像0
      • PlantUML による UML 図の描き方
        サムネイル画像-c788fffde5
        PlantUML はテキスト形式で表現されたシーケンス図やクラス図といった UML (Unified Modeling Language) 図の情報から画像を生成するためのツールです。簡単な使い方をまとめます。 インストール方法の選択 Atom や Eclipse のプラグインをインストールしてエディタから利用する方法、JAR をダウンロードして Java コマンドで実行する方法、Redmine ...
        kentakenta1/21/2020に更新
        いいねアイコン画像0
      • Akka HTTP サンプルコード (Scala)
        サムネイル画像-a98142497c
        Akka アクターを用いて実装された汎用 HTTP フレームワークです。Spray の後継です。コアモジュールである akka-http-core は 2016/2/17 に experimental が外れました。akka-http などのいくつかのサブモジュールは 2016/3/1 現在 experimental のままですが、基本的な
        雄太雄太10/7/2021に更新
        いいねアイコン画像0
      • Kestrel の使用例
        Kestrel は Message Queue (MQ) の実装のひとつです。一般に MQ はアプリケーション間やプロセス間、スレッド間で非同期に通信するために用いられます。メッセージの送信側は MQ に書き込めば受信側の応答を待たずに次の処理に非同期に進むことができます。Kestrel はわずか 2500 行程の Scala で実装されており JVM で動作します。MQ 自体はメモリ上に存在する...
        したくんしたくん10/12/2017に更新
        いいねアイコン画像0