サーチ…


前書き

Javaでは、 注釈はJavaソースコードに追加できる構文メタデータの一形式です。プログラム自体に含まれていないプログラムに関するデータを提供します 。注釈は注釈を付けるコードの操作に直接影響を与えません。クラス、メソッド、変数、パラメータ、パッケージに注釈を付けることができます。

構文

  • @AnnotationName // 'マーカーアノテーション'(パラメータなし)
  • @AnnotationName(someValue)// 'value'という名前のパラメータを設定する
  • @AnnotationName(param1 = value1)//名前付きパラメータ
  • @AnnotationName(param1 = value1、param2 = value2)//複数の名前付きパラメータ
  • @AnnotationName(param1 = {1、2、3})//名前付き配列パラメータ
  • @AnnotationName({value1})//名前が 'value'のパラメータとして単一要素を持つ配列

備考

パラメータタイプ

パラメータには、次の型の定数式と、これらの型の配列だけが許されます。

  • String
  • Class
  • プリミティブ型
  • 列挙型
  • 注釈タイプ

ビルトイン注釈

JavaのStandard Editionには、いくつかのアノテーションがあらかじめ定義されています。自分で定義する必要はなく、すぐに使用できます。コンパイラはメソッド、クラス、コードの基本的なチェックを可能にします。

@オーバーライド

この注釈はメソッドに適用され、このメソッドはスーパークラスのメソッドをオーバーライドするか、抽象スーパークラスのメソッド定義を実装する必要があると言います。このアノテーションが他の種類のメソッドで使用されている場合、コンパイラはエラーをスローします。

コンクリートスーパークラス

public class Vehicle {
   public void drive() {
        System.out.println("I am driving");
   }
}

class Car extends Vehicle {
    // Fine
    @Override
    public void drive() {
        System.out.prinln("Brrrm, brrm");
    }
}

抽象クラス

abstract class Animal  {
   public abstract void makeNoise(); 
}

class Dog extends Animal {
    // Fine
    @Override
    public void makeNoise() {
        System.out.prinln("Woof");
    }
}

動作しません

class Logger1 {
    public void log(String logString) {
        System.out.prinln(logString);
    }
}

class Logger2 {
    // This will throw compile-time error. Logger2 is not a subclass of Logger1. 
    // log method is not overriding anything
    @Override
    public void log(String logString) {
        System.out.println("Log 2" + logString);
    }
}

主な目的は、メソッドをオーバーライドしていると思われるミスタイプをキャッチすることですが、実際には新しいメソッドを定義しています。

class Vehicle {
   public void drive() {
        System.out.println("I am driving");
   }
}

class Car extends Vehicle {
    // Compiler error. "dirve" is not the correct method name to override.
    @Override
    public void dirve() {
        System.out.prinln("Brrrm, brrm");
    }
}

@Overrideの意味は時間とともに変化していることに注意してください。

  • Java 5では、注釈付きメソッドはスーパークラスチェーンで宣言された非抽象メソッドをオーバーライドする必要がありました。
  • Java 6以降では、注釈付きメソッドがクラススーパークラス/インタフェース階層で宣言された抽象メソッドを実装している場合にも、満足しています。

(これはコードをJava 5にバックポーティングするときに問題を引き起こすことがあります。)

@Deprecated

これはメソッドを非推奨とマークします。これにはいくつかの理由があります。

  • APIに欠陥があり、修正するのは実際的ではありません。

  • APIの使用はエラーにつながる可能性がありますが、

  • APIは別のAPIに取って代わられましたが、

  • APIは時代遅れですが、

  • APIは実験的なものであり、互換性のない変更を受けることがあります。

  • または上記の任意の組み合わせを含む。

非推奨の具体的な理由は、通常、APIのドキュメントに記載されています。


アノテーションを使用すると、コンパイラはエラーを発生させます。 IDEは、このメソッドを何らかの形で廃止されたものとして強調表示するかもしれません

class ComplexAlgorithm {
    @Deprecated
    public void oldSlowUnthreadSafeMethod() {
        // stuff here
    }
    
    public void quickThreadSafeMethod() {
        // client code should use this instead
    }
}

@SuppressWarnings

ほとんどすべての場合、コンパイラが警告を発するとき、最も適切なアクションは原因を修正することです。いくつかの例では(ジェネリックスコードは非安全な事前生成コードを使用しています)、これは可能ではないかもしれません。予期していて修正できない警告を抑制して、予期せぬ警告をより明確に表示できます。

このアノテーションは、クラス、メソッド、または行全体に適用できます。警告のカテゴリをパラメータとして取ります。

@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
    // several methods calling deprecated code here
}

@SuppressWarning("finally")
public boolean checkData() {
    // method calling return from within finally block
}

予期しない警告も抑制されないように、アノテーションのスコープを可能な限り制限する方がよいでしょう。たとえば、アノテーションのスコープを1行に限定します。

ComplexAlgorithm algorithm = new ComplexAlgorithm();
@SuppressWarnings("deprecation") algoritm.slowUnthreadSafeMethod(); 
// we marked this method deprecated in an example above

@SuppressWarnings("unsafe") List<Integer> list = getUntypeSafeList(); 
// old library returns, non-generic List containing only integers

このアノテーションでサポートされている警告は、コンパイラごとに異なる場合があります。 JLSでは、 unchecked deprecationていunchecked警告とdeprecation警告のみが具体的に言及されています。認識されない警告の種類は無視されます。

@SafeVarargs

型消去のため、 void method(T... t)void method(Object[] t)変換され、コンパイラは常にvarargsの使用がタイプセーフであることを確認できないことを意味します。例えば:

private static <T> void generatesVarargsWarning(T... lists) {

使用が安全である場合があります。この場合、 SafeVarargsアノテーションを使用してSafeVarargs注釈を付けて警告を抑制することができます。これはあなたの使用が安全でない場合でも警告を隠すことは明らかです。

@FunctionalInterface

これは、FunctionalInterfaceをマークするために使用されるオプションの注釈です。 FunctionalInterface仕様に準拠していない場合(単一の抽象メソッドを持つ)、コンパイラがエラーを発生させます。

@FunctionalInterface
public interface ITrade {
  public boolean check(Trade t);
}

@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}

リフレクションによるランタイムアノテーションチェック

JavaのReflection APIを使用すると、プログラマは実行時にクラスフィールド、メソッド、およびアノテーションに対してさまざまなチェックと操作を実行できます。ただし、実行時に注釈がすべて表示されるようにするには、以下の例に示すように、 RetentionPolicyRUNTIMEに変更する必要があります。

@interface MyDefaultAnnotation {

}

@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {

}

public class AnnotationAtRuntimeTest {

    @MyDefaultAnnotation
    static class RuntimeCheck1 {
    }
    
    @MyRuntimeVisibleAnnotation
    static class RuntimeCheck2 {
    }
    
    public static void main(String[] args) {
        Annotation[] annotationsByType = RuntimeCheck1.class.getAnnotations();
        Annotation[] annotationsByType2 = RuntimeCheck2.class.getAnnotations();

        System.out.println("default retention: " + Arrays.toString(annotationsByType));
        System.out.println("runtime retention: " + Arrays.toString(annotationsByType2));
    }
}

注釈タイプの定義

注釈タイプは@interface定義されます。パラメータは、通常のインタフェースのメソッドと同様に定義されます。

@interface MyAnnotation {
    String param1();
    boolean param2();
    int[] param3();  // array parameter 
}

デフォルト値

@interface MyAnnotation {
    String param1() default "someValue";
    boolean param2() default true;
    int[] param3() default {};
}

メタ注釈

メタ注釈は、注釈タイプに適用できる注釈です。特別な事前定義メタアノテーションは、アノテーションタイプの使用方法を定義します。

@ターゲット

@Targetメタアノテーションは、アノテーションを適用できるタイプを制限します。

@Target(ElementType.METHOD)
@interface MyAnnotation {
    // this annotation can only be applied to methods
}

@Target({ElementType.FIELD, ElementType.TYPE})配列表記を使用して複数の値を追加できます

利用可能な値

ElementType ターゲットターゲット要素の使用例
ANNOTATION_TYPE アノテーションタイプ
@Retention(RetentionPolicy.RUNTIME) 
@interface MyAnnotation
コンストラクタコンストラクタ
@MyAnnotation
public MyClass() {}
フィールドフィールド、列挙定数
@XmlAttribute
private int count;
LOCAL_VARIABLE メソッド内の変数宣言
for (@LoopVariable int i = 0; i < 100; i++) {
@Unused
String resultVariable;
}
パッケージ package(in package-info.java
@Deprecated
package very.old;
方法メソッド
@XmlElement
public int getCount() {...}
パラメータメソッド/コンストラクタのパラメータ
public Rectangle(
@NamedArg("width") double width,
@NamedArg("height") double height) {
...
}
タイプクラス、インタフェース、列挙型
@XmlRootElement
public class Report {}
Java SE 8
ElementType ターゲットターゲット要素の使用例
TYPE_PARAMETER タイプパラメータ宣言
public <@MyAnnotation T> void f(T t) {}
TYPE_USE タイプの使用
Object o = "42";
String s = (@MyAnnotation String) o;

@保持

@Retentionメタアノテーションは、アプリケーションコンパイルプロセスまたは実行中のアノテーション可視性を定義します。デフォルトでは、アノテーションは.classファイルに含まれていますが、実行時には表示されません。実行時にアノテーションにアクセスできるようにするには、そのアノテーションにRetentionPolicy.RUNTIMEを設定する必要があります。

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    // this annotation can be accessed with reflections at runtime
}

利用可能な値

RetentionPolicy 効果
クラスアノテーションは.classファイルで利用できますが、実行時には使用できません
ランタイムアノテーションは実行時に利用可能で、リフレクションを介してアクセスできます
ソースアノテーションはコンパイル時に使用できますが、 .classファイルには追加されません。注釈は、例えば、注釈プロセッサによって使用することができる。

@Documented

@Documentedメタアノテーションは、 javadocのようなAPIドキュメントジェネレータによって使用法が文書化されるべきアノテーションをマークするために使用されます。値はありません。 @Documentedを使用すると、アノテーションを使用するすべてのクラスが生成されたドキュメントページにそのアノテーションをリストします。 @Documentedを指定しないと、ドキュメンテーション内の注釈を使用するクラスを見ることはできません。

@継承されました

@Inheritedメタアノテーションは、クラスに適用されるアノテーションに関連しています。値はありません。アノテーションを@Inheritedとしてマークすると、アノテーションクエリが動作する方法が変更されます。

  • 継承されていない注釈の場合、照会は検査されるクラスのみを検査します。
  • 継承されたアノテーションについては、アノテーションのインスタンスが見つかるまでスーパークラスチェーンも(再帰的に)チェックされます。

スーパークラスのみが照会されることに注意してください。クラス階層のインターフェースにアタッチされた注釈は無視されます。

@繰り返し可能

@RepeatableメタアノテーションはJava 8で追加されました。アノテーションの複数のインスタンスがアノテーションのターゲットにアタッチできることを示します。このメタ注釈には値はありません。

実行時に注釈値を取得する

Reflectionを使用してAnnotationが適用されているメソッドまたはフィールドまたはクラスをフェッチし、目的のプロパティをフェッチすることで、Annotationの現在のプロパティを取得できます。

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String key() default "foo";
    String value() default "bar";
}


class AnnotationExample {
    // Put the Annotation on the method, but leave the defaults
    @MyAnnotation
    public void testDefaults() throws Exception {
        // Using reflection, get the public method "testDefaults", which is this method with no args
        Method method = AnnotationExample.class.getMethod("testDefaults", null);

        // Fetch the Annotation that is of type MyAnnotation from the Method
        MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

        // Print out the settings of the Annotation
        print(annotation);
    }

    //Put the Annotation on the method, but override the settings
    @MyAnnotation(key="baz", value="buzz")
    public void testValues() throws Exception {
        // Using reflection, get the public method "testValues", which is this method with no args
        Method method = AnnotationExample.class.getMethod("testValues", null);

        // Fetch the Annotation that is of type MyAnnotation from the Method
        MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

        // Print out the settings of the Annotation
        print(annotation);
    }

    public void print(MyAnnotation annotation) {
        // Fetch the MyAnnotation 'key' & 'value' properties, and print them out 
        System.out.println(annotation.key() + " = " + annotation.value());
    }

    public static void main(String[] args) {
        AnnotationExample example = new AnnotationExample();
        try {
            example.testDefaults();
            example.testValues();
        } catch( Exception e ) {
            // Shouldn't throw any Exceptions
            System.err.println("Exception [" + e.getClass().getName() + "] - " + e.getMessage());
            e.printStackTrace(System.err);
        }
    }
}

出力は次のようになります。

foo = bar
baz = buzz

注釈を繰り返す

Java 8までは、同じアノテーションの2つのインスタンスを1つの要素に適用できませんでした。標準的な回避策は、他のアノテーションの配列を保持するコンテナアノテーションを使用することでした。

// Author.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
    String value();
}

// Authors.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
    Author[] value();
}

// Test.java
@Authors({
    @Author("Mary"),
    @Author("Sam")
})
public class Test {
    public static void main(String[] args) {
        Author[] authors = Test.class.getAnnotation(Authors.class).value();
        for (Author author : authors) {
            System.out.println(author.value());
            // Output:
            // Mary
            // Sam
        }
    }
}
Java SE 8

Java 8では、 @Repeatableアノテーションを使用して、コンテナアノテーションをよりクリーンで透明な方法で使用@Repeatableます。まずこれをAuthorクラスに追加します:

@Repeatable(Authors.class)

これは、複数の@Authorアノテーションを@Authorsコンテナで囲まれているかのように扱うようJavaに指示します。また、 Class.getAnnotationsByType()を使用して、 @Author配列にそのコンテナではなく独自のクラスでアクセスすることもできます。

@Author("Mary")
@Author("Sam")
public class Test {
    public static void main(String[] args) {
        Author[] authors = Test.class.getAnnotationsByType(Author.class);
        for (Author author : authors) {
            System.out.println(author.value());
            // Output:
            // Mary
            // Sam
        }
    }
}

継承された注釈

デフォルトでは、クラスアノテーションはそれらを拡張する型には適用されません。これは、 @Inheritedアノテーションをアノテーション定義に追加することで変更できます

次の2つのアノテーションを考えてみましょう。

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}

そして

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}

3つのクラスに次のように注釈が付けられているとします。

@UninheritedAnnotationType
class A {
}

@InheritedAnnotationType
class B extends A {
}

class C extends B {
}

このコードを実行する

System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println("_________________________________");
System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));

アノテーションのパッケージに応じて、これに似た結果が出力されます。

null
@InheritedAnnotationType()
@InheritedAnnotationType()
_________________________________
@UninheritedAnnotationType()
null
null

注釈は、インタフェースではなくクラスから継承できることに注意してください。

アノテーション・プロセッサを使用したコンパイル時間処理

この例は、注釈付き要素のコンパイル時間チェックを行う方法を示しています。

アノテーション

@Setterアノテーションは、メソッドにマーカを適用することができます。注釈は、編集中に破棄され、その後は使用できなくなります。

package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Setter {
}

アノテーションプロセッサ

SetterProcessorクラスは、アノテーションを処理するためにコンパイラによって使用されます。 @Setterアノテーションで注釈を付けられたメソッドがpublicで、 setで始まり大文字が4文字目の名前の非staticメソッドであるかどうかをチェックします。これらの条件の1つが満たされない場合、エラーがMessager書き込まれます。コンパイラはこれをstderrに書き込みますが、他のツールではこの情報を別々に使用できます。たとえばNetBeans IDEでは、エディタにエラーメッセージを表示するために使用されるアノテーションプロセッサをユーザーが指定できます。

package annotation.processor;

import annotation.Setter;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

@SupportedAnnotationTypes({"annotation.Setter"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SetterProcessor extends AbstractProcessor {

    private Messager messager;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // get elements annotated with the @Setter annotation
        Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(Setter.class);

        for (Element element : annotatedElements) {
            if (element.getKind() == ElementKind.METHOD) {
                // only handle methods as targets
                checkMethod((ExecutableElement) element);
            }
        }

        // don't claim annotations to allow other processors to process them
        return false;
    }

    private void checkMethod(ExecutableElement method) {
        // check for valid name
        String name = method.getSimpleName().toString();
        if (!name.startsWith("set")) {
            printError(method, "setter name must start with \"set\"");
        } else if (name.length() == 3) {
            printError(method, "the method name must contain more than just \"set\"");
        } else if (Character.isLowerCase(name.charAt(3))) {
            if (method.getParameters().size() != 1) {
                printError(method, "character following \"set\" must be upper case");
            }
        }

        // check, if setter is public
        if (!method.getModifiers().contains(Modifier.PUBLIC)) {
            printError(method, "setter must be public");
        }

        // check, if method is static
        if (method.getModifiers().contains(Modifier.STATIC)) {
            printError(method, "setter must not be static");
        }
    }

    private void printError(Element element, String message) {
        messager.printMessage(Diagnostic.Kind.ERROR, message, element);
    }

    @Override
    public void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);

        // get messager for printing errors
        messager = processingEnvironment.getMessager();
    }

}

パッケージング

コンパイラによって適用されるには、注釈プロセッサをSPIで使用可能にする必要があります( ServiceLoaderを参照)。

これを行うには、 META-INF/services/javax.annotation.processing.Processorというテキストファイルを、他のファイルに加えてアノテーションプロセッサと注釈を含むjarファイルに追加する必要があります。ファイルには注釈プロセッサの完全修飾名を含める必要があります。つまり、次のようになります

annotation.processor.SetterProcessor

以下では、jarファイルがAnnotationProcessor.jarと呼ばれるものと仮定します。

アノテーション付きクラスの例

次のクラスは、保持ポリシーに従って正しい要素にアノテーションが適用されている、デフォルトパッケージのサンプルクラスです。しかしながら、注釈プロセッサのみが第2の方法を有効な注釈ターゲットとみなす。

import annotation.Setter;

public class AnnotationProcessorTest {
    
    @Setter
    private void setValue(String value) {}

    @Setter
    public void setString(String value) {}
    
    @Setter
    public static void main(String[] args) {}
    
}

javacでアノテーションプロセッサを使用する

注釈プロセッサがSPIを使用して検出された場合、注釈プロセッサは注釈付き要素を処理するために自動的に使用されます。例えばAnnotationProcessorTestクラスをコンパイルする

javac -cp AnnotationProcessor.jar AnnotationProcessorTest.java

次の出力が得られます

AnnotationProcessorTest.java:6: error: setter must be public
    private void setValue(String value) {}
                 ^
AnnotationProcessorTest.java:12: error: setter name must start with "set"
    public static void main(String[] args) {}
                       ^
2 errors

正常にコンパイルする代わりに。 .classファイルは作成されません。

これは、 javac -proc:noneオプションを指定することで防ぐことができます。代わりに、 -proc:only指定することで、通常のコンパイルを-proc:onlyすることもできます。

IDE統合

ネットビーンズ

注釈プロセッサは、NetBeansエディタで使用できます。これを行うには、注釈プロセッサをプロジェクト設定で指定する必要があります。

  1. Project Properties > Build > Compiling

  2. Enable Annotation ProcessingEnable Annotation ProcessingEnable Annotation Processing in EditorためのチェックマークをEnable Annotation Processing in Editor追加する

  3. アノテーションプロセッサリストの横にある[ Add ] Addクリックします

  4. 表示されるポップアップで、注釈プロセッサの完全修飾クラス名を入力し、[ Ok ]をクリックします。

結果

エディタウィンドウにカスタムエラーメッセージが表示される

注釈の背後にあるアイデア

Java言語仕様では、注釈について次のように説明しています。

アノテーションは、情報をプログラム構成に関連付けるマーカーですが、実行時には影響しません。

注釈は、型または宣言の前に現れます。型や宣言の両方に適用できる場所に表示することは可能です。
注釈が正確に適用されるものは、「メタ注釈」 @Targetによって管理されます。詳細は、 「アノテーション型の定義」を参照してください。

注釈はさまざまな目的で使用されます。 SpringやSpring-MVCのようなフレームワークでは、アノテーションを使用して、依存関係を注入する場所や要求をルーティングする場所を定義します。

他のフレームワークでは、アノテーションをコード生成に使用しています。 LombokとJPAはJava(およびSQL)コードを生成するアノテーションを使用する主要な例です。

このトピックでは、次の項目について包括的に説明します。

  • 独自の注釈を定義する方法

  • Java言語が提供する注釈は何ですか?

  • 実際に注釈はどのように使用されますか?

「this」とレシーバパラメータのアノテーション

Javaアノテーションが初めて導入されたとき、インスタンスメソッドのターゲットに注釈を付けるための規定や、内部クラスコンストラクタの隠しコンストラクタパラメータはありませんでした。これは、 レシーバー・パラメーター宣言を追加してJava 8で修正されました。 JLS 8.4.1を参照してください。

receiverパラメータは、インスタンスメソッドまたは内部クラスのコンストラクタのためのオプションの構文的デバイスです。インスタンスメソッドの場合、receiverパラメーターは、メソッドが呼び出されるオブジェクトを表します。内部クラスのコンストラクタの場合、receiverパラメータは新しく構築されたオブジェクトのすぐに囲まれたインスタンスを表します。どちらの場合でも、レシーバパラメータは、表現されたオブジェクトの型をソースコード内に示すことができるだけであり、その型に注釈を付けることができる。受信側パラメータは仮パラメータではありません。より正確には、変数の宣言ではなく(4.12.3)、メソッド呼び出し式や修飾されたクラスインスタンス作成式で引数として渡される値に決して束縛されず、実行時間。

次の例は、両方の種類のレシーバパラメータの構文を示しています。

public class Outer {
    public class Inner {
        public Inner (Outer this) {
           // ...
        }
        public void doIt(Inner this) {
           // ...
        }
    }
}

レシーバパラメータの唯一の目的は、アノテーションを追加できるようにすることです。たとえば、メソッドの呼び出し時にCloseableオブジェクトが閉じられていないことを宣言することを目的とするカスタム注釈@IsOpenがあるとします。例えば:

public class MyResource extends Closeable {
    public void update(@IsOpen MyResource this, int value) {
        // ...
    }

    public void close() {
        // ...
    }
}

1つのレベルでは、 @IsOpen上の注釈this単にドキュメントとして役立ち得ます。しかし、我々は潜在的にもっと多くを行うことができます。例えば:

  • 注釈プロセッサは、ことのランタイムチェックを挿入することができthis閉状態でないupdate呼ばれています。
  • コードチェッカーは、静的コード分析を実行して、 updateが呼び出されたときにthis 閉じることができるケースを見つけることができます

複数の注釈値を追加する

Annotationパラメータは、配列として定義されている場合は複数の値を受け入れることができます。例えば、標準アノテーション@SuppressWarningsは次のように定義されます。

public @interface SuppressWarnings {
    String[] value();
}

valueパラメータは文字列の配列です。配列初期化子に似た表記法を使用して、複数の値を設定できます。

@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "javadoc"})

単一の値だけを設定する必要がある場合は、大括弧を省略することができます。

@SuppressWarnings("unused") 


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow