【Java基礎】註解(Annotation)
Annotation,程式碼裡的特殊標記,在編譯、類載入、執行時被讀取,並執行相應的處理。
使用註解,在不改變原有邏輯的情況下,在原始檔中嵌入一些補充資訊。
Annotation提供了一種為程式元素設定元資料的方法。
Annotation是一個介面,通過反射來獲取指定程式元素的Annotation物件,通過Annotation物件來獲得註解裡的元資料。
Annotation不能影響程式程式碼的執行,無論增加、刪除 Annotation,程式碼都始終如一的執行。
一、基本Annotation
-
限定重寫父類方法:@Override
-
標記已過時:@Deprecated
-
抑制編譯器警告:@SuppressWarnings
-
Java7的“堆汙染”警告與@SafeVarargs
-
Java8的函式式介面與@FunctionallInterface
二、JDK的元Annotation
位於java.lang.annotation包下的6個Meta Annotation(元Annotation),其中有5個元Annotation用於修飾其他的Annotation定義,@Repeatable 專門用於定義Java8新增的重複註解。
1、@Retention
@Retention用於指定被修飾的Annotation可以保留多長時間。
value成員變數的值有三個:
-
RetentionPolicy .CLASS:編譯器把註解記錄在class檔案中。
-
RetentionPolicy.RUNTIME: 編譯器把註解記錄在class檔案中,執行Java程式時,JVM獲取註解資訊,程式可以通過反射獲取該註解資訊。
-
RetentionPolicy.SOURCE:只保留在原始碼中,編譯器註解丟棄。
@Retention(RetentionPolicy.RUNTIME) public @interface Column { ... }
2、@Target
用於被修飾的註解能用於修飾哪些程式單元。
取值 | 說明 |
---|---|
ElementType.ANNOTATION_TYPE | 給一個註解進行註解 |
ElementType.CONSTRUCTOR | 給構造方法進行註解 |
ElementType.FIELD | 給屬性進行註解 |
ElementType.LOCAL_VARIABLE | 可以給區域性變數進行註解 |
ElementType.METHOD | 可以給方法進行註解 |
ElementType.PACKAGE | 可以給包進行註解 |
ElementType.PARAMETEP | 可以給一個方法內的引數進行註解 |
ElementType.TYPE | 可以給一個型別進行註解,比如類,介面,列舉等 |
@Target(ElementType.TYPE)
public @interface TestAnnotation {
}
3、@Documented
用於指定被該元註解修飾的註解類將被javadoc工具提取成文件。
@Documented
public @interface TestAnnotation {
}
4、@Inherited
指定被它修飾的註解將具有繼承性——如果某個類使用了@Xxx註解(定義該註解時使用了@Inherited修飾)修飾,則其子類將自動被@Xxx修飾。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
@Test
public class A {}
public class B extends A {}
5、@Repeatable
Java新增的註解,允許使用多個相同型別的註解來修飾同一個類。
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
@interface Person{
String role default "";
}
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{
}
三、自定義Annotation
1、定義Annotation
定義新的Annotation型別使用@interface
,與定義一個介面類似。
public @interface MyTag {
//定義帶兩個成員變數的Annotation
//Annotation中的成員變數以方法的形式來定義
String name() default "yvonne";
int age() default 25;
}
定義Annotation之後,就可以在程式的任何地方使用該Annotation。
public class AnnotationTest {
@MyTag
public void info() {
...
}
}
2、使用Annotation
/***********註解宣告***************/
/**
* 水果名稱註解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
/**
* 水果顏色註解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 顏色列舉
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 顏色屬性
* @return
*/
Color fruitColor() default Color.GREEN;
}
/**
* 水果供應者註解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
/**
* 供應商編號
* @return
*/
public int id() default -1;
/**
* 供應商名稱
* @return
*/
public String name() default "";
/**
* 供應商地址
* @return
*/
public String address() default "";
}
/***********註解使用***************/
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
@FruitProvider(id=1,name="楊倩csdn",address="https://blog.csdn.net/happyniceyq")
private String appleProvider;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void setAppleProvider(String appleProvider) {
this.appleProvider = appleProvider;
}
public String getAppleProvider() {
return appleProvider;
}
public void displayName(){
System.out.println("水果的名字是:蘋果");
}
}
/***********註解處理器***************/
public class FruitInfoUtil {
public static void getFruitInfo(Class<?> clazz){
String strFruitName=" 水果名稱:";
String strFruitColor=" 水果顏色:";
String strFruitProvicer="供應商資訊:";
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields){
if(field.isAnnotationPresent(FruitName.class)){
FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
strFruitName=strFruitName+fruitName.value();
System.out.println(strFruitName);
}
else if(field.isAnnotationPresent(FruitColor.class)){
FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
System.out.println(strFruitColor);
}
else if(field.isAnnotationPresent(FruitProvider.class)){
FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
strFruitProvicer=" 供應商編號:"+fruitProvider.id()+" 供應商名稱:"+fruitProvider.name()+" 供應商地址:"+fruitProvider.address();
System.out.println(strFruitProvicer);
}
}
}
}
/***********輸出結果***************/
public class FruitRun {
/**
* @param args
*/
public static void main(String[] args) {
FruitInfoUtil.getFruitInfo(Apple.class);
}
}
====================================
水果名稱:Apple
水果顏色:RED
供應商編號:1 供應商名稱:楊倩csdn 供應商地址:https://blog.csdn.net/happyniceyq