摘要:注解功能編譯器可以使用注解來檢測錯誤和取消警告使用注解可以生成特定代碼,如使用注解簡化等某些注解可以在運行時進行檢查和操作。
原文發(fā)于微信公眾號jzman-blog,歡迎關(guān)注交流。
Java 注解(Annotation)又稱之為 Java 標注、元數(shù)據(jù),是 Java 1.5 之后加入的一種特殊語法,通過注解可以標注 Java 中的類、方法、屬性、參數(shù)、包等,可以通過反射原理對這些元數(shù)據(jù)進行訪問,注解的使用不會影響程序的正常運行,只會對編譯器警告等輔助工具產(chǎn)生影響。
注解功能編譯器可以使用注解來檢測錯誤和取消警告;
使用注解可以生成特定代碼,如 ButtferKnife 使用注解簡化 findViewById等;
某些注解可以在運行時進行檢查和操作。
定義注解注解的定義使用 @interface 作為關(guān)鍵字,實際上表示自動繼承了 java.lang.annotation.Annotation 接口,定義格式參考如下:
@元注解 public @interface AnnotationName{ //配置參數(shù)(參數(shù)類型 參數(shù)名稱()) String name() default "hello"; }
配置參數(shù)里面的類型包括基本類型、String、class、枚舉以及相關(guān)類型的數(shù)組,可以使用 default 設(shè)置配置參數(shù)的默認值,定義一個注解具體如下:
@Target(value = {ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface TestDefineAnnotation { String[] name() default "test"; }內(nèi)置注解
@Override
@Deprecated
@SuppressWarnings
下面是上面三個內(nèi)置注解的聲明:
//表示當前的方法將覆蓋超類中的方法,編譯時進行格式檢查 @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { } //表示一個類或者是方法不再建議使用,將其標記為過時,但還是可以使用 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); } //表示關(guān)閉不當?shù)木幾g器警告信息 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { }
根據(jù)對上面三個注解的聲明來看,@SuppressWarnings 中定義了一個數(shù)組,這個數(shù)組表示在該注解上具體的目標是那些,如可在 SuppressWarnings 上使用的值,常用的具體如下:
deprecation:使用了過時的類或方法時的警告
unused:有未使用的變量時的警告
unchecked:執(zhí)行了未檢查的轉(zhuǎn)換時的警告
fallthrough:當 switch 程序塊直接通往下一種情況而沒有 break 時的警告
path:在類路徑、源文件路徑等中有不存在的路徑時的警告
serial:當在可序列化的類上缺少serialVersionUID 定義時的警告
finally :任何 finally 子句不能正常完成時的警告
all:關(guān)于以上所有情況的警告
下面看一個案例,具體如下:
public void test() { long date = Date.parse("2018-04-22"); }
上面的代碼如果使用 eclipse 等其他 IDE 時會出現(xiàn)兩個警告,一是使用了過時的 API,二是變量 date 賦值后沒有被使用過,警告截圖如下:
當然, IDE 會提示是否添加 SuppressWarnings 來取消這些警告,前文中可以看到注解 @SuppressWarnings 的聲明中需要配置參數(shù),這個參數(shù)是一個數(shù)組,數(shù)組名稱是 value,可以省略這個名稱, 具體如下:
//不省略 public void test2() { @SuppressWarnings(value= {"deprecation", "unused"}) long date = Date.parse("2018-04-22"); } //省略 public void test2() { @SuppressWarnings({"deprecation", "unused"}) long date = Date.parse("2018-04-22"); }
來張截圖說明一下使用 @SuppressWarnings 的效果,具體如下:
如果只想取消一種警告可以這樣寫,具體如下:
//第一種 public void test2() { @SuppressWarnings(value = {"deprecation"}) long date = Date.parse("2018-04-22"); System.out.println(date); } //第二種 public void test2() { @SuppressWarnings({"deprecation"}) long date = Date.parse("2018-04-22"); System.out.println(date); }
注意:如果在定義注解的配置參數(shù)名稱為 value,那么可以在配置注解時可以省略 value,反之,使用其他名稱,則必須采用第一種方式,要指定配置參數(shù)名稱。
當然其他注解和 @SuppressWarnings 也比較類似, @Override、@Deprecated 由它們的聲明可知直接使用即可,不需要指定具體目標,在其聲明注解時用到了 @Documented、@Retention、@Target 等,這些用來注解其他注解的特殊注解稱之為元注解,具體請看下文。
元注解@Target
@Retention
@Documented
@Inherited
@Target 用來描述注解的使用范圍,它的聲明如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }
由 @Target 聲明可知使用 @Target 注解必須指定具體的 Java 成員,也就是該注解要使用到哪個位置,具體由枚舉 ElementType 中定義,具體如下:
public enum ElementType { TYPE, //類、接口、注解、枚舉 FIELD, //屬性(包括枚舉常量) METHOD, //方法 PARAMETER, //參數(shù) CONSTRUCTOR, //構(gòu)造方法 LOCAL_VARIABLE, //局部變量 ANNOTATION_TYPE,//注解 PACKAGE, //包 /** * 類型注解 * @since 1.8 */ TYPE_PARAMETER, TYPE_USE }
@Retention 表示在什么級別保存該注解的信息,它的聲明如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
由 @Retention 的聲明可知,使用 @Retention 時,必須指定保存celue(RetentionPolicy),具體值如下:
public enum RetentionPolicy { SOURCE, //在編譯時會被丟棄,僅僅在源碼中存在 CLASS, //默認策略,運行時就會被丟棄,僅僅在 class 文件中 RUNTIME //編譯時會將注解信息記錄到class文件,運行時任然保留,可以通過反射獲取注解信息 }
@Documented 和 @Inherited 都沒有配置參數(shù),是一種標記注解,@Documented 表示將該注解顯示到用戶文檔中,@Inherited 表示該注解只有使用在類上才會有效,而且該注解會被子類繼承。
類型注解在對元注解的說明中可知從 Java8 開始新增了類型注解,如果在注解 @Target 使用這種注解,表明該注解可以在對應的任何地方使用,如在 @Target 中指定 TYPE_PARAMETER 就可在自定義類型的聲明處使用該注解,如在 @Target 中指定 TYPE_USE 就可在任何類型前添加該類之間,主要是方便 Java 開發(fā)者使用類型注解和相關(guān)插件(Checker Framework)來檢查來在編譯期檢查運行時的異常。
下面分別定義指定 TYPE_PARAMETER 和 TYPE_USE 的注解,具體如下:
//1. TYPE_PARAMETER @Target(value = {ElementType.TYPE_PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface TypeParameterAnnotation { String value(); } //2. TYPE_USE @Target(value = ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME) public @interface TypeUseAnnotation { }
然后,在下面的案例中使用這兩個注解,具體如下:
/** * 測試注解 * @author jzman */ public class TestAnnotation { //... /** * ElementType.TYPE_PARAMETER * 使用在自定義類型聲明的時候,如注解@TypeParameterAnnotation * @param*/ static class TypeAnnotationA<@TypeParameterAnnotation(value="hello") T>{ /** * ElementType.TYPE_USE * 可以使用在任意類型前面(包含TYPE_PARAMETER) */ //創(chuàng)建實例 MyType myType = new @TypeUseAnnotation MyType(); //對象類型 Object obj = (@TypeUseAnnotation Object) myType; //泛型 ArrayList<@TypeUseAnnotation T> list = new ArrayList<>(); //參數(shù)中的類型 public String testA(@TypeUseAnnotation String test) { return "Hello"+test; } //枚舉 public void testB(@TypeUseAnnotation Color color) { //... } enum Color{ RED, GREEN, BLUE } } static class MyType{} }
其實注解的語法比較簡單,僅僅定義注解對實際開發(fā)是沒有幫助的,覺得注解只有在運行時通過反射獲取注解信息才是最重要的,注解與反射相關(guān)的內(nèi)容會在以后的推文中學習,到此對注解的認識就結(jié)束了。
可以選擇關(guān)注微信公眾號:jzman-blog 獲取最新更新,一起交流學習!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74224.html
摘要:楊充一定時間內(nèi)該點擊事件只能執(zhí)行一次用來修飾這是一個什么類型的注解。楊充自定義編譯器獲取遍歷,并生成代碼配置文件文件配置的作用是向系統(tǒng)注冊自定義注解處理器,執(zhí)行編譯時使用進行處理。 目錄介紹 01.創(chuàng)建項目步驟 1.1 項目搭建 1.2 項目功能 02.自定義注解 03.創(chuàng)建Processor 04.compiler配置文件 05.編譯jar 06.如何使用 07.編譯生成代...
摘要:從使用到原理學習線程池關(guān)于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實現(xiàn)在軟件開發(fā)中,分散于應用中多出的功能被稱為橫切關(guān)注點如事務安全緩存等。 Java 程序媛手把手教你設(shè)計模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經(jīng)風雨慢慢變老,回首走過的點點滴滴,依然清楚的記得當初愛情萌芽的模樣…… Java 進階面試問題列表 -...
閱讀 3870·2021-09-10 11:22
閱讀 2325·2021-09-03 10:30
閱讀 3660·2019-08-30 15:55
閱讀 1873·2019-08-30 15:44
閱讀 840·2019-08-30 15:44
閱讀 581·2019-08-30 14:04
閱讀 3041·2019-08-29 17:18
閱讀 1262·2019-08-29 15:04