JAVA ANNOTATION詳解
轉載自:http://william750214.javaeye.com/blog/298104
後設資料的作用
如果要對於後設資料的作用進行分類,目前還沒有明確的定義,不過我們可以根據它所起的作用,大致可分為三類:
l 編寫文件:通過程式碼裡標識的後設資料生成文件。
l 程式碼分析:通過程式碼裡標識的後設資料對程式碼進行分析。
l 編譯檢查:通過程式碼裡標識的後設資料讓編譯器能實現基本的編譯檢查。
基本內建註釋
@Override註釋能實現編譯時檢查,你可以為你的方法新增該註釋,以宣告該方法是用於覆蓋父類中的方法。如果該方法不是覆蓋父類的方法,將會在編譯時報錯。例如我們為某類重寫toString()方法卻寫成了tostring(),並且我們為該方法新增了@Override註釋;
@Deprecated的作用是對不應該在使用的方法新增註釋,當程式設計人員使用這些方法時,將會在編譯時顯示提示資訊,它與javadoc裡的@deprecated標記有相同的功能,準確的說,它還不如javadoc @deprecated,因為它不支援引數,
注意:要了解詳細資訊,請使用 -Xlint:deprecation 重新編譯。
@SuppressWarnings與前兩個註釋有所不同,你需要新增一個引數才能正確使用,這些引數值都是已經定義好了的,我們選擇性的使用就好了,引數如下:
deprecation 使用了過時的類或方法時的警告
unchecked 執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合儲存的型別
fallthrough 當 Switch 程式塊直接通往下一種情況而沒有 Break 時的警告
path 在類路徑、原始檔路徑等中有不存在的路徑時的警告
serial 當在可序列化的類上缺少 serialVersionUID 定義時的警告
finally 任何 finally 子句不能正常完成時的警告
all 關於以上所有情況的警告
注意:要了解詳細資訊,請使用 -Xlint:unchecked 重新編譯。
定製註釋型別
好的,讓我們建立一個自己的註釋型別(annotation type)吧。它類似於新建立一個介面類檔案,但為了區分,我們需要將它宣告為@interface,如下例:
public @interface NewAnnotation {
}
使用定製的註釋型別
我們已經成功地建立好一個註釋型別NewAnnotation,現在讓我們來嘗試使用它吧,如果你還記得本文的第一部分,那你應該知道他是一個標記註釋,使用也很容易,如下例:
public class AnnotationTest {
@NewAnnotation
public static void main(String[] args) {
}
}
新增變數
J2SE 5.0裡,我們瞭解到內建註釋@SuppressWarnings()是可以使用引數的,那麼自定義註釋能不能定義引數個數和型別呢?答案是當然可以,但引數型別只允許為基本型別、String、Class、列舉型別等,並且引數不能為空。我們來擴充套件NewAnnotation,為之新增一個String型別的引數,示例程式碼如下:
public @interface NewAnnotation {
String value();
}
使用該註釋的程式碼如下:正如你所看到的,該註釋的使用有兩種寫法,這也是在之前的文章裡所提到過的。如果你忘了這是怎麼回事,那就再去翻翻吧。
public class AnnotationTest {
@NewAnnotation("Just a Test.")
public static void main(String[] args) {
sayHello();
}
@NewAnnotation(value="Hello NUMEN.")
public static void sayHello() {
// do something
}
}
為變數賦預設值
我們對Java自定義註釋的瞭解正在不斷的增多,不過我們還需要更過,在該條目裡我們將瞭解到如何為變數設定預設值,我們再對NewAnnotaion進行修改,看看它會變成什麼樣子,不僅引數多了幾個,連類名也變了。但還是很容易理解的,我們先定義一個列舉型別,然後將引數設定為該列舉型別,並賦予預設值。
public @interface Greeting {
public enum FontColor {RED, GREEN, BLUE};
String name();
String content();
FontColor fontColor() default FontColor.BLUE;
}
限定註釋使用範圍
當我們的自定義註釋不斷的增多也比較複雜時,就會導致有些開發人員使用錯誤,主要表現在不該使用該註釋的地方使用。為此,Java提供了一個ElementType列舉型別來控制每個註釋的使用範圍,比如說某些註釋只能用於普通方法,而不能用於建構函式等。下面是Java定義的ElementType列舉:
package java.lang.annotation;
public enum ElementType {
TYPE, // Class, interface, or enum (but not annotation)
FIELD, // Field (including enumerated values)
METHOD, // Method (does not include constructors)
PARAMETER, // Method parameter
CONSTRUCTOR, // Constructor
LOCAL_VARIABLE, // Local variable or catch clause
ANNOTATION_TYPE, // Annotation Types (meta-annotations)
PACKAGE // Java package
}
下面我們來修改Greeting註釋,為之新增限定範圍的語句,這裡我們稱它為目標(Target)使用方法也很簡單,如下:
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
正如上面程式碼所展示的,我們只允許Greeting註釋標註在普通方法和建構函式上,使用在包申明、類名等時,會提示錯誤資訊。
註釋保持性策略
public enum RetentionPolicy {
SOURCE,// Annotation is discarded by the compiler
CLASS,// Annotation is stored in the class file, but ignored by the VM
RUNTIME// Annotation is stored in the class file and read by the VM
}
RetentionPolicy的使用方法與ElementType類似,簡單程式碼示例如下:
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
文件化功能
Java提供的Documented元註釋跟Javadoc的作用是差不多的,其實它存在的好處是開發人員可以定製Javadoc不支援的文件屬性,並在開發中應用。它的使用跟前兩個也是一樣的,簡單程式碼示例如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
值得大家注意的是,如果你要使用@Documented元註釋,你就得為該註釋設定RetentionPolicy.RUNTIME保持性策略。為什麼這樣做,應該比較容易理解,這裡就不提了。
標註繼承
繼承應該是Java提供的最複雜的一個元註釋了,它的作用是控制註釋是否會影響到子類,簡單程式碼示例如下:
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
讀取註釋資訊
當我們想讀取某個註釋資訊時,我們是在執行時通過反射來實現的,如果你對元註釋還有點印象,那你應該記得我們需要將保持性策略設定為RUNTIME,也就是說只有註釋標記了@Retention(RetentionPolicy.RUNTIME)的,我們才能通過反射來獲得相關資訊,下面的例子我們將沿用前面幾篇文章中出現的程式碼,並實現讀取AnnotationTest類所有方法標記的註釋並列印到控制檯。好了,我們來看看是如何實現的吧:
public class AnnotationIntro {
public static void main(String[] args) throws Exception {
Method[] methods = Class.forName(
"com.gelc.annotation.demo.customize.AnnotationTest")
.getDeclaredMethods();
Annotation[] annotations;
for (Method method : methods) {
annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(method.getName() + " : "
+ annotation.annotationType().getName());
}
Java併發程式設計中,用到了一些專門為併發程式設計準備的 Annotation。
主要包括三類:
1、類 Annotation(註解)
就像名字一樣,這些註解是針對類的。主有要以下三個:
@Immutable
@ThreadSafe
@NotThreadSafe
@ThreadSafe 是表示這個類是執行緒安全的。具體是否真安全,那要看實現者怎麼實現的了,反正打上這個標籤只是表示一下。不執行緒安全的類打上這個註解也沒事兒。
@Immutable 表示,類是不可變的,包含了 @ThreadSafe 的意思。
@NotThreadSafe 表示這個類不是執行緒安全的。如果是執行緒安全的非要打上這個註解,那也不會報錯。
這三個註解,對使用者和維護者是有益的,使用者可以立即看出來這個類是否是執行緒安全的,維護者則是可以根據這個註解,重點檢查執行緒安全方面。另外,程式碼分析工具可能會利用這個註解。
2、域 Annotation(註解)
域註解是對類裡面成員變數加的註解。
3、方法 Annotation(註解)
方法註解是對類裡面方法加的註解。
域註解和方法註解都是用@GuardedBy( lock )來標識。裡面的Lock是告訴維護者:這個狀態變數,這個方法被哪個鎖保護著。這樣可以強烈的提示類的維護者注意這裡。
@GuardedBy( lock )有以下幾種使用形式:
1、@GuardedBy( "this" ) 受物件內部鎖保護
2、@GuardedBy( "fieldName" ) 受 與fieldName引用相關聯的鎖 保護。
3、@GuardedBy(
"ClassName.fieldName" ) 受 一個類的靜態field的鎖 儲存。
4、@GuardedBy( "methodName()" ) 鎖物件是 methodName() 方法的返值,受這個鎖保護。
5、@GuardedBy( "ClassName.class"
) 受 ClassName類的直接鎖物件保護。而不是這個類的某個例項的鎖物件。
?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29900383/viewspace-1698135/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java註解(Annotation)詳解Java
- Java —— 註解(Annotation)Java
- Java Annotation 註解Java
- Java 註解(Annotation)Java
- java-Annotation註解Java
- Java之註解(Annotation)Java
- Java 註解Annotation研究Java
- 【Java.Core】註解 - AnnotationJava
- java annotationJava
- Java進階(一)Annotation(註解)Java
- Java註解(Annotation):請不要小看我!Java
- Java 註解 (Annotation)淺入深出Java
- Java建立AnnotationJava
- java 的annotationJava
- 元註解——java.lang.annotation.Target(1.8)Java
- Java自定義Annotation,通過反射解析AnnotationJava反射
- java反射——反射AnnotationJava反射
- 關於Java註解(annotation)的簡單理解Java
- Java學習之註解Annotation實現原理Java
- JAVA(五)反射機制/AnnotationJava反射
- 解決報錯error the @annotation pointcut expression is only supported at Java 5ErrorExpressJava
- Java Annotation 必須掌握的特性Java
- Java註解詳解Java
- Java 註解詳解Java
- Spring(三)——註解方式(Annotation)Spring
- 【framework】spring-註解(annotation)FrameworkSpring
- java反射詳解Java反射
- Java Stream 詳解Java
- Java 反射詳解Java反射
- 【Java】JDBC詳解JavaJDBC
- Java SPI詳解Java
- 詳解 Java NIOJava
- Java鎖詳解Java
- java CountDownLatch 詳解JavaCountDownLatch
- Java RMI詳解Java
- Java容器詳解Java
- java方法詳解Java
- Annotation