JAVA註解是什麼?

JAVA註解

註解是什麼

註解(Annotation)是一種應用於類、方法、參數、變量、構造器及包聲明中的特殊修飾符。它是一種由JSR-175標準選擇用來描述元數據的一種工具。

通俗的將就是一個輔助功能,可以傳遞數據,可以給編譯器制定一個標準,要是你不按這個標準,就會編譯錯誤。

常用註解(內置)

  • @Override

  • @Deprecated

  • @SuppressWarnings

  • @SafeVarargs

  • @FunctionalInterface

@Override

@Override 用在方法上,表示這個方法重寫了父類的方法,如toString()。
如果父類沒有這個方法,那麼就無法編譯通過,可以用來控制代碼或檢查正確性

@Deprecated

@Deprecated 表示這個方法已經過期,不建議開發者使用。(暗示在將來某個不確定的版本,就有可能會取消掉)

@SuppressWarnings

@SuppressWarnings Suppress英文的意思是抑制的意思,這個註解的用處是忽略警告信息。

1.deprecation:使用了不贊成使用的類或方法時的警告(使用@Deprecated使得編譯器產生的警告);
2.unchecked:執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合保存的類型; 關閉編譯器警告;
3.fallthrough:當 Switch 程序塊直接通往下一種情況而沒有 Break 時的警告;
4.path:在類路徑、源文件路徑等中有不存在的路徑時的警告;
5.serial:當在可序列化的類上缺少 serialVersionUID 定義時的警告;
6.finally:任何 finally 子句不能正常完成時的警告;
7.rawtypes 泛型類型未指明
8.unused 引用定義了,但是沒有被使用
9.all:關於以上所有情況的警告。

//例如在方法前面加上
@SuppressWarnings({ "rawtypes", "unused" })
//可以忽略不寫泛型帶來的警示
@SafeVarargs

@SafeVarargs 這是1.7 之後新加入的基本註解. 如例所示,當使用可變數量的參數的時候,而參數的類型又是泛型T的話,就會出現警告。 這個時候,就使用@SafeVarargs來去掉這個警告。

@SafeVarargs註解只能用在參數長度可變的方法或構造方法上,且方法必須聲明爲static或final,否則會出現編譯錯誤。

@FunctionalInterface

@FunctionalInterface這是Java1.8 新增的註解,用於約定函數式接口。
函數式接口概念: 如果接口中只有一個抽象方法(可以包含多個默認方法或多個static方法),該接口稱爲函數式接口。函數式接口其存在的意義,主要是配合Lambda 表達式來使用。

//具體就是在只有一個抽象方法的前面使用(不包括static方法)
@FunctionalInterface
public interface Example {
    public void sayHello(String str);
}

使用該註解後就可以使用Lambda表達式來表示該接口的一個實現(java8特性,以前一般都用匿名函數)

Example e = str -> System.out.println("Hello " + str);
//箭頭前面是參數,後面是方法實現,這樣以後e就是一個實現了接口方法的類。
//若是有多個語句多個參數,請用{},()把它括起來。

自定義註解

先來看看@Override的註解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
//其中@interface是用來定義一個註解的
//註解上面的@Target這些是元註解,就是註解的註解
元註解

@Documented – 註解是否將包含在JavaDoc中
@Retention – 什麼時候使用該註解
@Target – 註解用於什麼地方
@Inherited – 是否允許子類繼承該註解
@Documented – 一個簡單的Annotations標記註解,表示是否將註解信息添加在java文檔中。
@Retention – 定義該註解的生命週期。

元註解可以設置參數,也可以不設置參數,像@Document就沒有參數,作用是可以使用javadoc命令將註解生成相關文檔

@Target

@Target表示這個註解能放在什麼位置上,如@Target({METHOD,TYPE}),表示他可以用在方法和類型上(類和接口),但是不能放在屬性等其他位置。 可以選擇的位置列表如下:
ElementType.TYPE:能修飾類、接口或枚舉類型
ElementType.FIELD:能修飾成員變量
ElementType.METHOD:能修飾方法
ElementType.PARAMETER:能修飾參數
ElementType.CONSTRUCTOR:能修飾構造器
ElementType.LOCAL_VARIABLE:能修飾局部變量
ElementType.ANNOTATION_TYPE:能修飾註解
ElementType.PACKAGE:能修飾包

@Retention

@Retention 表示生命週期,@Retention可選的值有3個:
RetentionPolicy.SOURCE: 註解只在源代碼中存在,編譯成class之後,就沒了。@Override 就是這種註解。
RetentionPolicy.CLASS: 註解在java文件編程成.class文件後,依然存在,但是運行起來後就沒了。@Retention的默認值,即當沒有顯式指定@Retention的時候,就會是這種class類型。
RetentionPolicy.RUNTIME: 註解在運行起來之後依然存在,程序可以通過反射獲取這些信息,下面的例子就是這樣。

@Inherited

@Inherited 表示該註解具有繼承性,即父類的註解信息能否給子類使用。

@Documented

在用javadoc命令生成API文檔後,DBUtil的文檔裏會出現該註解說明。

示例

@Repeatable(java1.8)

當沒有@Repeatable修飾的時候,註解在同一個位置,只能出現一次,重複做兩次就會報錯了。
使用@Repeatable之後,就可以在同一個地方使用多次了。
@interface MyHints {
    Hint[] value();
}
 
@Repeatable(MyHints.class)
@interface Hint {
    String value();
}

//兩個使用方法
@MyHints({@Hint("hint1"), @Hint("hint2")})

@Hint("hint1")
@Hint("hint2")

//解析時返回的是Hint[] 而不是MyHints
Filterable.class.getAnnotationsByType(Filter.class)
註解元素
//比如下面的JDBC連接註解,IP(),database()這些類似接口中函數聲明的就是註解元素,用來存儲數據。
@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface JDBCConfig {
     String ip();
     int port() default 3306;
     String database();
     String encoding();
     String loginName();
     String password();
}
註解解析
JDBCConfig config = DBUtil.class.getAnnotation(JDBCConfig.class)//獲得註解類
String ip = config.ip();										//獲得註解元素
int port = config.port();
String database = config.database();
String encoding = config.encoding();
String loginName = config.loginName();
String password = config.password();

屬性設置:

value:是一個特殊的屬性,若在設置值時只有一個value屬性需要設置或者其他屬性都採用默認值時 ,那麼value=可以省略,直接寫所設置的值即可。
eg:@SuppressWarnings(“deprecation”)

爲屬性指定缺省值(默認值):
eg:String value() default “blue”; //定義在註解類中

數組類型的屬性:
eg:int[] arrayArr() default {3,4,5,5};//定義在註解類中
SunAnnotation(arrayArr={3,9,8}) //設置數組值
Note:如果數組屬性中只有一個元素時,屬性值部分可以省略大括號。
eg:SunAnnotation(arrayArr=9)

註解類型的屬性:

eg:MetaAnnotation annotationAttr() default @MetaAnnotation(“lhm”);

其中MetaAnnotation是註解類,註解也是類,是.java文件

TIPS

AnnotationDemo.class.isAnnotationPresent(SunAnnotation.class)
//用於描述某類中是否存在某類註解,放回true or false
    
SunAnnotation annotation = (SunAnnotation) AnnotationDemo.class.getAnnotation(SunAnnotation.class);
//返回一個註解類,若從方法獲取註解用.class.getMethod("XXX").getAnnotation();

annotation.annotationClass()
//獲取註解的類名稱
    
//JAVA8新增
ElementType.TYPE_PARAMETER 表示該註解能寫在類型變量的聲明語句中。
ElementType.TYPE_USE 表示該註解能寫在使用類型的任何語句中。(聲明語句、泛型和強制轉換語句中的類型)

詳細怎麼使用可以參考這篇文章https://blog.csdn.net/sun_promise/article/details/51315032

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章