1. はじめに
皆さんこんにちは!2024年度新入社員の松澤です。
配属先ではJavaを使ってごりごり開発に携わる予定です!!
皆さんはJava100本ノックをやったことはありますか?Javaに精通した諸先輩方には物足りないかもしれないですが、研修で初級程度のJavaしか触ったことのないペーペーの新入社員には結構難解です。わからないところだらけですが、なんとか調べながら解いているところです。
その中で、おもろいやんと思ったアノテーションの自作について今回はレポートしていきます!
2. アノテーションってなんやねん
JavaJavaしまくった方ならもうご存じかもしれないですが、そうです。@Override
とかのあれです。初級Java研修の時には@Override
ぐらいしか出なかったのに次に受講したSpring研修では@PathVariable
、@OneToMany
、 @GetMapping
とかわんさかでてきて覚えるのに苦労しました…。
アノテーションは日本語で「注釈」という意味があります。一般的な書籍を読んでいると、引用元などが注釈として記載されている場合があり、ちょこっと便利ですよね~!
Javaでもアノテーションを使うことでクラス・メソッド・フィールド等に付属情報を付けることができます。
2.1. アノテーションの特徴
そんなアノテーションですが以下のような特徴があります。
- アノテーションは
@ + 名前
のような形で表現される。 - クラスやメソッドに対して補足的な情報をつけることができる。
2.2. アノテーションのメリット
他にも以下のようなメリットもあります。
- コンパイラと組み合わせて適切な処理が行われないとエラーを起こしたり逆にエラーを抑制したりできる。
@Override
:オーバーライドしていなかったら警告を表示。@SuppressWarnings
:コンパイラによる警告を抑制するためのアノテーション。引数でどのような警告を抑制するかを指定できる。
- アノテーションをもとにして、コンパイル時に新しいクラスを生成できる。
- リフレクションAPIを用いて、特定のアノテーションを対象にして処理を行うことができる。(具体例は後述します)
いろいろ便利な機能があるんですね~。
3. アノテーションつくってみた
アノテーションの特徴を述べまくりましたが、アノテーションは自作することができます。
今回は、AuthorAnnotaion
というアノテーションを作成して、AuthorAnnotaion
からコード編集者を判定するプログラムを作成していきたいと思います。
※通常はJavadocで@author
タグにコード編集者を記載しますが、今回はアノテーションを作成するのが目的なので、AuthorAnnotaion
を用いて編集者を判定します。
3.1. @interfaceによりアノテーションを定義
アノテーションを定義する際には@interface
キーワードを指定します。
さらにフィールドを指定することで、アノテーションで利用できる属性を指定することができます。
今回のプログラムでは、アノテーションに指定した属性を用いて編集者を分類するので、author
属性を定義します。default
キーワードでデフォルト値を指定します。
メタアノテーションの定義
メタアノテーションとは、アノテーションに関する「適用範囲」や「保持期限」などを制御するアノテーションです。
@Target
:クラス内のどこを対象として付与するアノテーションであるかを定義- 今回は
ElementType.FIELD
を指定してフィールドのみに付与させる。
- 今回は
@Retention
:アノテーションの保持期間を定義- 今回は
RetentionPolicy.RUNTIME
を指定し、このプログラムの実行中にアノテーション情報を取得できるようにします。
- 今回は
AuthorAnnotation.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //アノテーション情報をJVMに保持し、実行中にアノテーション情報を取得できるようにする @Retention(RetentionPolicy.RUNTIME) //フィールドに付与するアノテーションであることを示す @Target({ElementType.FIELD}) public @interface AuthorAnnotation { // AuthorAnnotaionに付与する編集者情報 String author() default "noname"; }
3.2. アノテーションを付与する
先ほど作成した@AuthorAnnotation
をAttach
クラスに付与していきます。
AuthorAnnotation
インターフェースで@Target({ElementType.FIELD})
を指定したので、フィールドにアノテーションを付与していきます。
今回は編集者に関するフィールドを4つ作成しました。
me
friend
:それぞれauthor
属性に値を指定shiranhito
:author
属性に値を指定しない(デフォルト値が適用)senpai
:@AuthorAnnotation
を付与しない
Attach.java
public class Attach { //フィールドにアノテーションを付与 @AuthorAnnotation(author = "Matsuzawa") final private String me = "Matsuzawa"; @AuthorAnnotation(author = "friend") final private String friend = "friend"; @AuthorAnnotation() final private String shiranhito = "shiranhito"; private String senpai; }
3.3. アノテーションを活用する
Main
クラスにreturnJudgeResult
メソッドを定義することによって編集者判定を行いました。
Attach
クラスのインスタンスを作成- リフレクションを用いてフィールドにアタッチされる
author
を抽出 - 抽出した
author
値からif文で編集者判定
リフレクションによって、Classの型やFieldの値を動的に呼び出すことができます。今回はFieldの情報を取得したいのでField
クラスを用いて情報を取得しました。
さらに、アノテーションが付与されない場合はauthor
がNullになってしまうのでNullPointerException
をcatchしました。
Main.java
import java.lang.reflect.Field; public class Main { public static void main(String[] args) throws NoSuchFieldException { //編集者判定 printJudgeResult("me"); printJudgeResult("friend"); printJudgeResult("shiranhito"); printJudgeResult("senpai"); } /** * AttachクラスのフィールドにアタッチされたAuthorAnnotaionのauthor値から * 編集者判定結果を返却する * * @param fieldName * @throws NoSuchFieldException */ private static void printJudgeResult(String fieldName) throws NoSuchFieldException { try { // Attachクラスのインスタンス作成 final Attach attach = new Attach(); // リフレクションを用いてフィールドにアタッチされるauthorを抽出 final Field field = attach.getClass().getDeclaredField(fieldName); final AuthorAnnotation anotation = field.getAnnotation(AuthorAnnotation.class); final String author = anotation.author(); //authorによる判定 if (author.equals("Matsuzawa")) { System.out.println(fieldName + ":編集者は松澤武志です"); } else if (author.equals("noname")) { System.out.println(fieldName + ":編集者の登録がありません"); } else { System.out.println(fieldName + ":編集者は" + author + "です"); } // アノテーションが付与されていない場合に例外処理を発生させる } catch (NullPointerException e) { System.out.println(fieldName + ":アノテーションが付与されてへんで"); } } }
3.4. 出力結果
こちらのメインメソッドを実行すると以下の出力結果が得られました。
出力結果
me:編集者は松澤武志です friend:編集者はfriendです shiranhito:編集者の登録がありません senpai:アノテーションが付与されてへんで
author
属性に指定された文字によって分類されていることがわかります!
4. 最後に
こんな感じでアノテーションを作ってみました。意外と簡単に作ることができましたが
@SuppressWarnings
のように警告を抑制するようなアノテーションもいつか自作出来たら良いですね~。
アノテーションを作成する機会自体は、開発を行う上でも結構出て来るらしいので、また作りまくっていきたいと思います!
最後までご覧いただきありがとうございました!皆さんもアノテーションを作りまくってみてください~。