1. 程式人生 > >annotation(註解) 解析與例項一

annotation(註解) 解析與例項一

What is annotation?

Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.

常見用途

Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
比如我們常見的@Override

,@SuppressWarnings編譯器通過註解,去檢測錯誤或者抑制warning.

Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
編譯時部署時通過工具處理註解,以方便生產程式碼。

Runtime processing — Some annotations are available to be examined at runtime.
執行時檢測註解

具體使用

Compiler 檢測@得知它後邊跟了註解。

  • 註解可以跟元素elements,元素(name-value形式)。
  • 如果註解中僅有一個元素,則可以直接寫value。@SuppressWarnings("unchecked")
  • 如果註解中沒有元素,則可以直接省略。@EBook

  • 有重複型別的註解,被稱為重複註解(Repeating annotations) ,jdk1.8引入。

@Author(name = "Jane Doe")
@Author(name = "John Smith")

示例 :

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
, ) class MyClass() { ... } @SuppressWarnings("unchecked") void myMethod() { ... } @Author(name = "Jane Doe") @EBook class MyClass { ... } @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }
  • 對於註解的型別,都是在java.lang.annotation中定義,預定義的註解型別有:
    java.lang.Deprecated
    (implements java.lang.annotation.Annotation): 該方法(或類、介面等等)棄用。(使用時,注意javadoc中用 @deprecated)
public class Snippet { 
    // Javadoc comment follows
    /**
     * @deprecated explanation of why it was deprecated
     */
    @Deprecated
    static void deprecatedMethod() {
    }
}

java.lang.@Override (implements java.lang.annotation.Annotation)
編譯器通過這個註釋去檢測重寫的正確性。

java.lang.@SuppressWarnings (implements java.lang.annotation.Annotation)用於抑制程式碼中提示的warning資訊。

 // use a deprecated method and tell 
   // compiler not to generate a warning
   @SuppressWarnings("deprecation")
    void useDeprecatedMethod() {
        // deprecation warning
        // - suppressed
        objectOne.deprecatedMethod();
    }

java.lang.@SafeVarargs (implements java.lang.annotation.Annotation)
用於抑制可變引數使用報出的warning資訊.

java.lang.FunctionalInterface (implements java.lang.annotation.Annotation)
jdk1.8引入,宣告功能性介面。

元註解:用於宣告其他註解的註解
java.lang.annotation.@Retention:表示如何保留被標識的註解:

  • RetentionPolicy.SOURCE – The marked annotation is retained only in the source level and is ignored by the compiler.
    原始碼級別註釋保留,被 java compiler 忽略編譯。
  • RetentionPolicy.CLASS – The marked annotation is retained by the compiler at compile time, but is ignored by the Java Virtual Machine (JVM).
    java compiler 編譯時保留註解。被JVM忽略。
  • RetentionPolicy.RUNTIME – The marked annotation is retained by the JVM so it can be used by the runtime environment.
    執行時保留該註解,被JVM保留。

java.lang.annotation.@Documented
通過javadoc tool 處理該註釋,僅作為文件。

java.lang.annotation.@Target
用來表示被標識的註解用於指定的型別。

  • ElementType.ANNOTATION_TYPE can be applied to an annotation type.
  • ElementType.CONSTRUCTOR can be applied to a constructor.
  • ElementType.FIELD can be applied to a field or property.
  • ElementType.LOCAL_VARIABLE can be applied to a local variable.
  • ElementType.METHOD can be applied to a method-level annotation.
  • ElementType.PACKAGE can be applied to a package declaration.
  • ElementType.PARAMETER can be applied to the parameters of a method.
  • ElementType.TYPE can be applied to any element of a class.

java.lang.annotation@Inherited
表示這個註解可以繼承超類註解。注意:這個註解只能用來宣告類
示例:

package inherited.test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

}




 package inherited.test;

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 UninheritedAnnotationType {

}

package inherited.test;
@UninheritedAnnotationType
class A {

}



package inherited.test;
@InheritedAnnotationType
class B extends A {

}


package inherited.test;
class C extends B {

}
/**
 * 
 */
package inherited.test;


public class Test {
    public static void main(String[] args) {

    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));
}
}

output:

null
@inherited.test.InheritedAnnotationType()
@inherited.test.InheritedAnnotationType()
_________________________________
@inherited.test.UninheritedAnnotationType()
null
null