#概要
業務でSpring Bootを使うことになり、はるか昔の新卒のJava研修の内容しかなかった頭にアノテーションの概念をインプットする必要に迫られた。
#参考にしたサイト
ものすごいわかりやすかったです
http://www.atmarkit.co.jp/ait/articles/1105/19/news127.html
特にこの例でスッと入ってきました
アノテーションとは、「注釈」という意味です。Javadocコメントは開発者に対してプログラムがどういうものかを説明するために使いましたが、これと同様に、コンパイラや実行環境に対してプログラムがどういうものかを伝えたいことがあります。
後述する具体的な例を見れば分かりますが、Javaではアノテーションをプログラムに記述することにより、コンパイラで出力される警告メッセージを抑制したり、実行環境によってプログラムの動作を変更したりできます。
実行時の利用についてはこちらを参考にさせていただきました。
https://www.qoosky.io/techs/390aad36f8
#やってみる
java version 1.8.0_181
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
src
└test
└java
└annotation
├ Main.java
└ MethodInformation.java
##内容
ただのマーカーとしてのアノテーション型を作って設定してみます。
package test.java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// Targetアノテーションを付けることで「何につけられるアノテーションなのか?」を指定できる
@Target(ElementType.TYPE)
public @interface MethodInformation {
}
package test.java.annotation;
@MethodInformation
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
###ElementType の種類って?
こちらをどうぞ
java.lang.annotation.ElementType.javapublic enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
##実行
何の問題もなく出力されています。特に何もしないアノテーションなので出力内容に変更はありません。
![WS000061.JPG](https://qiita-image-store.s3.amazonaws.com/0/275553/41e78129-45de-b69a-a570-27adfc5352c2.jpeg)
![WS000062.JPG](https://qiita-image-store.s3.amazonaws.com/0/275553/89dd90fb-6cfb-b6a7-da38-b6bd348dfcec.jpeg)
##メソッドにしか付けられないアノテーションにしてみる
```java:MethodInformation.java
package test.java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // メソッドにしか付けられません
public @interface MethodInformation {
}
#クラス内部からアノテーションの情報を取得する
package test.java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) // コンパイル→実行時にもアノテーションの情報を保持しておく必要がある
public @interface MethodInformation {
}
package test.java.annotation;
@MethodInformation
public class Main {
public static void main(String[] args) {
Main mainInstance = new Main();
Class clazz = mainInstance.getClass();
// Mainクラスに設定されているアノテーションの種類を得る
System.out.println(clazz.getAnnotation(MethodInformation.class));
System.out.println("Hello World!");
}
}
##RetentionPolicyの種類って?
こちらをどうぞ
java.lang.annotation.RetentionPolicy.javapublic enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
##実行結果
@test.java.annotation.MethodInformation() が出力されてるのがわかります
##値が設定されたアノテーションの値を取得
アノテーション要素と呼ばれるものを作って、その値を取得してみる
package test.java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInformation {
String testString();
int testInt();
}
package test.java.annotation;
@MethodInformation(testString = "this is test", testInt = 12345)
public class Main {
public static void main(String[] args) {
Main mainInstance = new Main();
Class clazz = mainInstance.getClass();
MethodInformation methodInformation = (MethodInformation)clazz.getAnnotation(MethodInformation.class);
// アノテーション型内ではメソッドで定義されている
System.out.println(methodInformation.testString());
System.out.println(methodInformation.testInt());
System.out.println("Hello World!");
}
}
#自分自身をアノテーションしても大丈夫
package test.java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MethodInformation(testString = "this is test double", testInt = 1234512345) // 自分自身をアノテーション
public @interface MethodInformation {
String testString() default "test";
int testInt() default 1234;
}
package test.java.annotation;
@MethodInformation
public class Main {
public static void main(String[] args) {
Main mainInstance = new Main();
Class clazz = mainInstance.getClass();
MethodInformation methodInformation = (MethodInformation)clazz.getAnnotation(MethodInformation.class);
System.out.println(methodInformation.testString());
System.out.println(methodInformation.testInt());
System.out.println("Hello World!");
}
}