Java SE11 Gold 対策メモ   --アノテーション編

# 概要

- Java SE11 Gold 試験用にまとめていた自分用メモ
- [こちらの記事](https://qiita.com/leonis_sk/items/a378fc03e79c74d4727c)を参考にSE8⇒SE11の変更点等をまとめていきます。

## アノテーションの仕様
アノテーションは各要素に対して注釈を付ける機能です
**[java.lang.annotation.Annotation](https://bead.inf.elte.hu/files/java/api/java.base/java/lang/annotation/class-use/Annotation.html)** パッケージで宣言

|主なアノテーション|説明|
|:--|:--|
|@&#xFFF0;Override|スーパークラスのメソッドをオーバーライドすることを示す|
|@&#xFFF0;FunctionalInterface|関数型インターフェースであることを示す|
|@&#xFFF0;Deprecated|非推奨の要素であることを示す|
|@&#xFFF0;SuppressWarnings|コンパイラの警告を無効にする|
|@&#xFFF0;SafeVarargs|安全でない可変長引数に対する警告を無視する|



### @&#xFFF0;Override
スーパークラスのメソッドをオーバーライドすることを示す

```java:@Override
class Super{
	void test1(){}
	void test2(){}
}

public class Main extends Super{

	@Override
	void test1(){}
	//@Override
	//void hoge(){}	//コンパイルエラー

}
```


### @&#xFFF0;FunctionalInterface
+ 関数型インターフェースであることを示す

```java:@FunctionalInterface
@FunctionalInterface
interface A<T>{
	int num = 0;

	T Test_1();
	//void Test_2();	//2つ目以降の抽象メソッドはエラー
	static  void Test_3() {}
	default void Test_4() {}
	private void Test_5() {}

	@Override 
	boolean equals(Object obj);    //Objectクラスのpublicメソッドは抽象メソッドとして可

	@Override
	String toString();
}
```
```java:失敗例
@FunctionalInterface     //関数型インターフェースとしての要件を満たしていないためエラー
interface B<T>{
	boolean equals(Object obj);
}
```


### @&#xFFF0;Deprecated
+ 非推奨の要素であることを示す
<br>※IDE次第では、宣言元、呼び出し先にて~~Super~~となる(Eclipseにて確認済み)

```java:@Deprecated
class Super{

	@Deprecated
	Super(){}
	Super(int num){}
}

public class Main {

	public static void main(String[] args) {
		Super super1 = new Super();    //非推奨となり警告が出る
		Super super2 = new Super(10);    //こちらはならない
	}
}
```



### @&#xFFF0;SuppressWarnings
+ コンパイラの警告を無効にする
+ "unchecked"は型の仕様に関連する(List<>を指定せずに宣言)
<br>警告を抑制する
+ "deprecation"は@&#xFFF0;Deprecatedがつけられた要素を
<br>使用した際の警告を抑制する

```java:@SuppressWarnings
/*
 * 1.@SuppressWarnings(value = {"deprecation"})
 * 2.@SuppressWarnings(value = {"deprecation", unchecked})
 * 3.@SuppressWarnings("deprecation")
 * 4.@SuppressWarnings({"deprecation"})
 * 5.@SuppressWarnings({"deprecation", unchecked})
 */

@SuppressWarnings(value = {"deprecation"})
public class Main {

	public static void main(String[] args) {
		Date date = new Date("2021/06/28");
		System.out.println(date);
	}
}
```

### @&#xFFF0;SafeVarargs
+ 安全でない可変長引数に対する警告を無視する

```java:@SafeVarargs
public class Main {
	/*
	 * @SafeVarargsをつける場合
	 * final, static, privateのいずれか
	 * でなければならない
	 */
	@SafeVarargs
	static void test(String... str) {
		System.out.println(str[0]);
	}
	public static void main(String[] args) {
		String str = "Hello";
		test(str);
	}
}
```

##カスタムアノテーション

+ 独自のアノテーションを実装することができる
+ 型は**@&#xFFF0;interface**を使用します
+ `java.lang.annotation.Annotation`インターフェースを継承している
+ 注釈としての機能を目的とする

```java:実装例
public @interface MyAnnot {
	public enum RANK {A, B, C, D};

	//void test_1();    //コンパイルエラー
	/*	
	*引数は、基本データ型、String型、
	*Class型、列挙型、アノテーション型、
	*上記の1次元配列のみ許可
	*/

	int test_2();
	//RANK test_3() default null;    //コンパイルエラー defalutにnullは指定できない
	RANK test_4() default RANK.B;
	String value();
}
```
```java:使用例
public class Main {
	@MyAnnot(test_2 = 0, value = "")	//defaltで宣言されたtest_3は省略可能
	public void method() {
	}
}
```

##メタアノテーション
+ 主にカスタムアノテーションに注釈を付ける為に用いる
+ アノテーションの特性や使い方を制御することができる

|主なアノテーション|説明|
|:--|:--|
|@&#xFFF0;Documented|Javadoc API ドキュメントの出力にも反映するようにする|
|@&#xFFF0;Target|アノテーションを付与する要素を限定する|
|@&#xFFF0;Retention|アノテーションをソースコードもしくはクラスファイルまで保持するかなどを制御する|
|@&#xFFF0;Inherited|サブクラスにアノテーションを引き継ぐことを示す|
|@&#xFFF0;Repeatable|同じ場所に複数回適用する|

### @&#xFFF0;Documented
+ Javadoc API ドキュメントの出力にも反映するようにする

```java
@Documented    //APIドキュメントにMyAnnotアノテーションを付与した要素が反映される
public @interface MyAnnot {
	public enum RANK {A, B, C, D};
	RANK test();
}
```

### @&#xFFF0;Target
+ 「このアノテーションはクラス宣言で使用する」といった適材箇所を限定する
+  `ElementType`列挙型で用意されている
+  複数選択が可能

```java
@Target(ElementType.METHOD)    //メソッドにのみ付与できる
public @interface MyAnnot {
	public enum RANK {A, B, C, D};
	RANK test();
}
```

```java
//@Target_MyAnnot(test = RANK.A)    //メソッドのみの制限があるのでコンパイルエラー
public class Main{
	@Target_MyAnnot(test = RANK.A)    //メソッドに付与しているので正しい
	public void method(int a) {
	}
}
```
### @&#xFFF0;Retention
+ ソースコード、クラスファイル、クラスファイル実行時において
<br>アノテーションの挙動を制御する
+ `RetentionPolicy`列挙型で用意されている
+ デフォルトは(RetentionPolicy.CLASS)

↓↓↓↓↓↓@&#xFFF0;SuppressWarningsを抜粋↓↓↓↓↓↓

```java
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
     String[] value();
}
```

### @&#xFFF0;Inherited
+ サブクラスにスーパークラスのアノテーションを引き継ぐことを示す
+ クラスアノテーションのみ適用される

```java
@Inherited
public @interface MyAnnot {
    public enum RANK {A, B, C, D};
    RANK test();
}
```

### @&#xFFF0;Repeatable
+ 複数回可能となるアノテーションの定義
+ 複数のデータを保持できる、**コンテナアノテーション**を用いる



```java:失敗例
@MyAnnot("test1")
public class Main{
  //@MyAnnot("test2")    //コンパイルエラー
  //@MyAnnot("test3")    //コンパイルエラー
  public void method(int a) {
  }
}
```

```java:成功例
public @interface MyAnnotContainer {    //コンテナアノテーション
  public MyAnnot[] value();             //複数のデータを格納できるように配列で宣言する
}

@Repeatable(MyAnnotContainer.class)    //引数にコンテナアノテーション
public @interface MyAnnot {
  public String value();
}

@MyAnnot("test1")
public class Main{
  @MyAnnot("test2")    //    コンパイル可能
  @MyAnnot("test3")    
  public void method(int a) {
  }
}
```


# 参考書
[オラクル認定資格教科書 Javaプログラマ Gold SE11](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Gold-SE11%EF%BC%88%E8%A9%A6%E9%A8%93%E7%95%AA%E5%8F%B71Z0-816%EF%BC%89-%E5%B1%B1%E6%9C%AC-ebook/dp/B08P55ZJNY/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=java+gold&qid=1624931447&sr=8-3)
[徹底攻略Java SE 8 Gold問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-8-Gold%E5%95%8F%E9%A1%8C%E9%9B%86%EF%BC%BB1Z0-809%EF%BC%BD%E5%AF%BE%E5%BF%9C-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-ebook/dp/B01LXSG1G9/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=java+gold&qid=1624931447&sr=8-4)