読者です 読者をやめる 読者になる 読者になる

結局アノテーションって何ができるんすか

なんかいろいろ出来るって程度にしか理解してないので一回じゃっとアレする。
現状知ってるのは、

  1. なんかコンパイルエラーの条件に出来る(@Overrideとか)
  2. アノテーションがついてますよ、ってのを見て特別な動作をさせられる(AOPで差し込まれたメソッドの中で特定のメソッドについてるアノテーションを見て動作を分岐したり)
  3. なんか特別な動きをさせる。(よくわからん、@Autowiredとか。2と同じか?) 程度で、ようするによくわかってない。

以下はこの人を読んでのメモです?
Lesson: Annotations (The Java™ Tutorials > Learning the Java Language)

ざっくりなんなんすか

  • あくまでコードの注釈である。(このメソッドはオーバーライドされたメソッドですよみたいな)
  • 処理に直接の影響を与えない。
何に使うんすか
  • コンパイラに何かを教えてあげるため。エラーを検知させたり警告を出したり。(@Overrideのあれとか)
  • コンパイルとデプロイのため。(//TODO ここよくわかんねえ。上の例で言う3のような気がする。)コンパイル結果になんか影響を与える的な何か・・・?もしくは別のツールアノテーションを読んでなんか生成する的な話?
  • 実行中になんかするため。(上でいう2)

ざっくりまとめると、

  • コンパイルした時点で何かを起こせる。
  • コンパイルした結果に影響を与えられる。
  • 実行結果に影響を与えられる。

みたいなニュアンスですかね。

Lesson: Annotations (The Java™ Tutorials > Learning the Java Language)

ふつうのアノテーション

どんな感じに書くんすか

一番単純なパターン

@Entry

要素をもってる系

@Excretion( type = "softy", smell = "strong" )

要素が1つなら要素名は省けるぞ

@Excretion("softy")

いっぱいつけられるぞ

@Excretion( type = "softy", smell = "strong" )
@Vulgar
class SoftyPoop extends Poop { ... }
Java8から同じアノテーションもいっぱいいけるらしい。
参考: Repeating Annotationをちょっと試してみた - tomoTakaの日記

アノテーションの型定義はjava.lang or java.lang.annotationのパッケージでいける。

どこにつけられるんすか(注釈を)

  • クラス
  • フィールド
  • メソッド
  • その他の要素(は?)
    Java8からはここにも書けますよ
  • インスタンス作成時に。 new @Interned MyObject();
  • キャスト時に。 myString = (@NonNull String) str;
  • implementsの件に。
    class UnmodifiableList implements @Readonly List<@Readonly T> { ... }
  • throwsの件に。
    void monitorTemperature() throws @Critical TemperatureException { ... }

Annotations Basics (The Java™ Tutorials > Learning the Java Language > Annotations)

どうやって自分で型を宣言すんの

import java.lang.annotation.*;
@Documented
public @interface Movie {
       String title();
       String director() default "Alan Smithee";
       String[] actors();
}
  • インターフェースのメソッドっぽい感じで値?を定義する?
  • デフォルト値を持てる

@Documentedアノテーションの意味については以下を
Java - @Documented アノテーションの意味 - Qiita

Declaring an Annotation Type (The Java™ Tutorials > Learning the Java Language > Annotations)

すでに定義されてるアノテーションいろいろ

@Deprecated

  • 今後使わないでねマーク
  • こいつがついてるクラス、フィールド、メソッドを使うとコンパイル時に警告が出る
/**
 * うんこクラス
 * @deprecated
 * きたないから使用禁止
 */
@Deprecated
public class うんこ {
}

Javadocになんで使っちゃ駄目か書こう。javadocの@deprecatedは小文字から始まるので注意

@Override

  • オーバーライドしたメソッドにつけよう
  • つけなくても問題なく動くけどミスを防げるぞ
  • オーバーライドしたメソッドでないのについてるとコンパイル時にエラーがでるぞ

@SuppressWarnings

  • 他の何かが出そうとする警告を潰せるぞ
  • 潰す警告の種類を指定できるぞ
  • @SuppressWarnings("deprecation")で、deplication警告だけ潰せる。こんな感じで複数潰すことも。@SuppressWarnings({"deprecation", "unchecked"})
    警告の種類ってなんすか

    コンパイラが吐き出す警告は何らかのカテゴリに所属してる。例えば、

  • deplication 廃止されてるものを呼び出した時の警告
  • unchecked ジェネリクス登場以前のレガシーなコードを書いた時の警告(型を指定してないコレクション使ったりとか)
  • その他いろいろ Java警告抑止方法メモ(Hishidama's Java SuppressWarnings Memo)

@SafeVarargs

  • パラメータ化された型の可変長引数を使った時に出てくる"ヒープ汚染が云々"の警告を抑制する。
  • メソッドがstaticでないとコンパイルエラーになる。

ヒープ汚染について
非具象化可能仮パラメータを可変長引数メソッドに使用する場合のコンパイラの警告の改善

@FunctionalInterface

  • 関数インターフェースだよマーク

関数インターフェースについて
Java関数型インターフェースメモ(Hishidama's Java8 Functional Interface Memo)

アノテーションにつけるアノテーション

を、メタ・アノテーションて呼ぶ。

@Retention

これをつけたアノテーションがアプリケーションのライフサイクルの中でどこまで残るの?を指定できる。 以下のいずれかを指定できる。

  • RetentionPolicy.SOURCE ソース上だけ。コンパイラには無視される。(@Overrideにはこいつが付いてるんだがどうやってコンパイルエラーにしてんだ?)//TODO
  • RetentionPolicy.CLASS コンパイラは認識する。JVMには無視される。
  • RetentionPolicy.RUNTIME 実行時もアノテーションが見える。
    無視される、ではなくてなかったことにされる、くらいのニュアンスなの?わからん?
@Documented

Javadocからドキュメントを生成した時にこのアノテーションがついてるアノテーションがついてる要素はアノテーションついてるよってのをドキュメントに乗せてくれるらしい。
@DocumentedAnotation
@NoDocumentedAnotation
public void test(){}
みたいな場合に、testメソッドのドキュメントに@DocumentedAnotationついてるよってのは記載されるけど@NoDocumentedAnotationついてるよっての記載されない感じですか。eclipseで要素をフォーカスした時に出るJavadocにはどっちにしろ記載されてる。よくわからん。

Java - @Documented アノテーションの意味 - Qiita

@Target

そのアノテーションどこにつけられんの?を定義できる。

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD}) //このアノテーションはクラスとメソッドにしかつけられない
public @interface Movie {
       String title();
       String director() default "Alan Smithee";
       String[] actors();
}
@Inherited

@InheritedなアノテーションAがついたクラスの継承クラスも勝手にアノテーションAがつく。

@Repeatable

複数指定したいアノテーションにつけるアノテーション
よくわからん
Javaアノテーションメモ(Hishidama's Java annotation Memo)

どうやって使うんすか(コンパイル時)

きえええええ!!!
Java - Pluggable Annotation Processing API 使い方メモ - Qiita

どうやって使うんすか(実行時)

きえええええ!!!
Javaのリフレクションとアノテーションについて - public static void main
基本的にこのパターンはリフレクションでアノテーション何ついてんの?って調べて処理を分岐させてうんぬんて感じなんすかね??

結論

AOPとリフレクションについて勉強したら何かが見えてくる気がする。