java定義注解

小伙伴們。今天我們來說說注解、標志@ 。針對java不同版本來說,注解的出現是在jdk1.5 但是在jdk1.5版本使用注解必須繼續類的方法的重寫,不能用于實現的接口中的方法實現,在jdk1.6環境下對于繼續和實現都是用。

jdk1.5版本內置了三種標準的注解:

@Override,表示當前的方法定義將覆蓋超類中的方法。

@Deprecated,使用了注解為它的元素編譯器將發出警告,因為注解@Deprecated是不贊成使用的代碼,被棄用的代碼。

@SuppressWarnings,關閉不當編輯器警告信息。

Java還提供了4中注解,專門負責新注解的創建:
@Target:

表示該注解可以用于什么地方,可能的ElementType參數有:
CONSTRUCTOR:構造器的聲明
FIELD:域聲明(包括enum實例)
LOCAL_VARIABLE:局部變量聲明
METHOD:方法聲明
PACKAGE:包聲明
PARAMETER:參數聲明
TYPE:類、接口(包括注解類型)或enum聲明

@Retention

表示需要在什么級別保存該注解信息。可選的RetentionPolicy參數包括:
SOURCE:注解將被編譯器丟棄
CLASS:注解在class文件中可用,但會被VM丟棄
RUNTIME:VM將在運行期間保留注解,因此可以通過反射機制讀取注解的信息

@Document

將注解包含在Javadoc中

@Inherited

允許子類繼承父類中的注解

下面我們自己來新建一個注解。在我們開發中。經常會使用自己設置的注解

首先我們創建一個注解類

package com.java.api;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/**定義注解* @Target:表示該注解可以用于什么地方,可能的ElementType參數有:
CONSTRUCTOR:構造器的聲明
FIELD:域聲明(包括enum實例)
LOCAL_VARIABLE:局部變量聲明
METHOD:方法聲明
PACKAGE:包聲明
PARAMETER:參數聲明
TYPE:類、接口(包括注解類型)或enum聲明
@Retention表示需要在什么級別保存該注解信息。可選的RetentionPolicy參數包括:
SOURCE:注解將被編譯器丟棄
CLASS:注解在class文件中可用,但會被VM丟棄
RUNTIME:VM將在運行期間保留注解,因此可以通過反射機制讀取注解的信息* * */
public class UseCase{
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCases{public String id();public String description() default "no description";
}
}

然后我那使用注解

package com.java.api;import com.java.api.UseCase.UseCases;/*** 使用注解:* * */
public class PasswordUtils {@UseCases(id="47",description="Passwords must contain at least one numeric")public boolean validatePassword(String password) {return (password.matches("\\w*\\d\\w*"));}@UseCases(id ="48")public String encryptPassword(String password) {return new StringBuilder(password).reverse().toString();}
}

最后我們來測試我們寫的注解:

package com.java.api;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import com.java.api.UseCase.UseCases;/***解析注解:* * */
public class UserCaseTest {
public static void main(String[] args) {List<Integer> useCases = new ArrayList<Integer>();Collections.addAll(useCases, 47, 48, 49, 50);trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {for (Method m : cl.getDeclaredMethods()) {//獲得注解的對象UseCases uc = m.getAnnotation(UseCases.class);if (uc != null) {System.out.println("Found Use Case:" + uc.id() + " "+ uc.description());useCases.remove(new Integer(uc.id()));}}for (int i : useCases) {System.out.println("Warning: Missing use case-" + i);}
}
}

總結:

java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。
注解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annotation 包中

java自定義注解和運行時靠反射獲取注解。

其它

1、Annotation的工作原理:
JDK5.0中提供了注解的功能,允許開發者定義和使用自己的注解類型。該功能由一個定義注解類型的語法和描述一個注解聲明的語法,讀取注解的API,一個使用注解修飾的class文件和一個注解處理工具組成。Annotation并不直接影響代碼的語義,但是他可以被看做是程序的工具或者類庫。它會反過來對正在運行的程序語義有所影響。Annotation可以沖源文件、class文件或者在運行時通過反射機制多種方式被讀取。2@Override注解:
java.lang
注釋類型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
表示一個方法聲明打算重寫超類中的另一個方法聲明。如果方法利用此注釋類型進行注解但沒有重寫超類方法,則編譯器會生成一條錯誤消息。@Override注解表示子類要重寫父類的對應方法。Override是一個Marker annotation,用于標識的Annotation,Annotation名稱本身表示了要給工具程序的信息。下面是一個使用@Override注解的例子:class A {private String id;A(String id){this.id = id;}@Overridepublic String toString() {return id;}
}
3@Deprecated注解:
java.lang
注釋類型 Deprecated
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated@Deprecated 注釋的程序元素,不鼓勵程序員使用這樣的元素,通常是因為它很危險或存在更好的選擇。在使用不被贊成的程序元素或在不被贊成的代碼中執行重寫時,編譯器會發出警告。@Deprecated注解表示方法是不被建議使用的。Deprecated是一個Marker annotation。下面是一個使用@Deprecated注解的例子:class A {private String id;A(String id){this.id = id;}@Deprecatedpublic void execute(){System.out.println(id);}public static void main(String[] args) {A a = new A("a123");a.execute();}
}
4@SuppressWarnings注解:
java.lang
注釋類型 SuppressWarnings
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)
public @interface SuppressWarnings
指示應該在注釋元素(以及包含在該注釋元素中的所有程序元素)中取消顯示指定的編譯器警告。注意,在給定元素中取消顯示的警告集是所有包含元素中取消顯示的警告的超集。例如,如果注釋一個類來取消顯示某個警告,同時注釋一個方法來取消顯示另一個警告,那么將在此方法中同時取消顯示這兩個警告。根據風格不同,程序員應該始終在最里層的嵌套元素上使用此注釋,在那里使用才有效。如果要在特定的方法中取消顯示某個警告,則應該注釋該方法而不是注釋它的類。@SuppressWarnings注解表示抑制警告。下面是一個使用@SuppressWarnings注解的例子:@SuppressWarnings("unchecked")
public static void main(String[] args) {List list = new ArrayList();list.add("abc");
}
5、自定義注解:
使用@interface自定義注解時,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其他細節。在定義注解時,不能繼承其他的注解或接口。自定義最簡單的注解:public @interface MyAnnotation {}
使用自定義注解:public class AnnotationTest2 {@MyAnnotationpublic void execute(){System.out.println("method");}
}
5.1、添加變量:
public @interface MyAnnotation {String value1();
}
使用自定義注解:public class AnnotationTest2 {@MyAnnotation(value1="abc")public void execute(){System.out.println("method");}
}
當注解中使用的屬性名為value時,對其賦值時可以不指定屬性的名稱而直接寫上屬性值接口;除了value意外的變量名都需要使用name=value的方式賦值。5.2、添加默認值:
public @interface MyAnnotation {String value1() default "abc";
}
5.3、多變量使用枚舉:
public @interface MyAnnotation {String value1() default "abc";MyEnum value2() default MyEnum.Sunny;
}
enum MyEnum{Sunny,Rainy
}
使用自定義注解:public class AnnotationTest2 {@MyAnnotation(value1="a", value2=MyEnum.Sunny)public void execute(){System.out.println("method");}
}
5.4、數組變量:
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定義注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})public void execute(){System.out.println("method");}
}
6、設置注解的作用范圍:
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention
指示注釋類型的注釋要保留多久。如果注釋類型聲明中不存在 Retention 注釋,則保留策略默認為 RetentionPolicy.CLASS。只有元注釋類型直接用于注釋時,Target 元注釋才有效。如果元注釋類型用作另一種注釋類型的成員,則無效。public enum RetentionPolicy
extends Enum<RetentionPolicy>
注釋保留策略。此枚舉類型的常量描述保留注釋的不同策略。它們與 Retention 元注釋類型一起使用,以指定保留多長的注釋。CLASS
編譯器將把注釋記錄在類文件中,但在運行時 VM 不需要保留注釋。
RUNTIME
編譯器將把注釋記錄在類文件中,在運行時 VM 將保留注釋,因此可以反射性地讀取。
SOURCE
編譯器要丟棄的注釋。
@Retention注解可以在定義注解時為編譯程序提供注解的保留策略。屬于CLASS保留策略的注解有@SuppressWarnings,該注解信息不會存儲于.class文件。6.1、在自定義注解中的使用例子:
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {String[] value1() default "abc";
}
7、使用反射讀取RUNTIME保留策略的Annotation信息的例子:
java.lang.reflect接口 AnnotatedElement
所有已知實現類:AccessibleObject, Class, Constructor, Field, Method, Package
表示目前正在此 VM 中運行的程序的一個已注釋元素。該接口允許反射性地讀取注釋。由此接口中的方法返回的所有注釋都是不可變并且可序列化的。調用者可以修改已賦值數組枚舉成員的訪問器返回的數組;這不會對其他調用者返回的數組產生任何影響。如果此接口中的方法返回的注釋(直接或間接地)包含一個已賦值的 Class 成員,該成員引用了一個在此 VM 中不可訪問的類,則試圖通過在返回的注釋上調用相關的類返回的方法來讀取該類,將導致一個 TypeNotPresentException。isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定類型的注釋存在于此元素上,則返回 true,否則返回 false。此方法主要是為了便于訪問標記注釋而設計的。參數:annotationClass - 對應于注釋類型的 Class 對象返回:如果指定注釋類型的注釋存在于此對象上,則返回 true,否則返回 false拋出:NullPointerException - 如果給定的注釋類為 null從以下版本開始:1.5getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
如果存在該元素的指定類型的注釋,則返回這些注釋,否則返回 null。參數:annotationClass - 對應于注釋類型的 Class 對象返回:如果該元素的指定注釋類型的注釋存在于此對象上,則返回這些注釋,否則返回 null拋出:NullPointerException - 如果給定的注釋類為 null從以下版本開始:1.5getAnnotations
Annotation[] getAnnotations()
返回此元素上存在的所有注釋。(如果此元素沒有注釋,則返回長度為零的數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。返回:此元素上存在的所有注釋從以下版本開始:1.5getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注釋。與此接口中的其他方法不同,該方法將忽略繼承的注釋。(如果沒有注釋直接存在于此元素上,則返回長度為零的一個數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。返回:直接存在于此元素上的所有注釋從以下版本開始:1.5下面是使用反射讀取RUNTIME保留策略的Annotation信息的例子:自定義注解:@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定義注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})@Deprecatedpublic void execute(){System.out.println("method");}
}
讀取注解中的信息:public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {AnnotationTest2 annotationTest2 = new AnnotationTest2();//獲取AnnotationTest2的Class實例Class<AnnotationTest2> c = AnnotationTest2.class;//獲取需要處理的方法Method實例Method method = c.getMethod("execute", new Class[]{});//判斷該方法是否包含MyAnnotation注解if(method.isAnnotationPresent(MyAnnotation.class)){//獲取該方法的MyAnnotation注解實例MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//執行該方法method.invoke(annotationTest2, new Object[]{});//獲取myAnnotationString[] value1 = myAnnotation.value1();System.out.println(value1[0]);}//獲取方法上的所有注解Annotation[] annotations = method.getAnnotations();for(Annotation annotation : annotations){System.out.println(annotation);}
}
8、限定注解的使用:
限定注解使用@Target@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Target
指示注釋類型所適用的程序元素的種類。如果注釋類型聲明中不存在 Target 元注釋,則聲明的類型可以用在任一程序元素上。如果存在這樣的元注釋,則編譯器強制實施指定的使用限制。 例如,此元注釋指示該聲明類型是其自身,即元注釋類型。它只能用在注釋類型聲明上:@Target(ElementType.ANNOTATION_TYPE)public @interface MetaAnnotationType {...}
此元注釋指示該聲明類型只可作為復雜注釋類型聲明中的成員類型使用。它不能直接用于注釋:@Target({}) public @interface MemberType {...}
這是一個編譯時錯誤,它表明一個 ElementType 常量在 Target 注釋中出現了不只一次。例如,以下元注釋是非法的:@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})public @interface Bogus {...}
public enum ElementType
extends Enum<ElementType>
程序元素類型。此枚舉類型的常量提供了 Java 程序中聲明的元素的簡單分類。這些常量與 Target 元注釋類型一起使用,以指定在什么情況下使用注釋類型是合法的。ANNOTATION_TYPE
注釋類型聲明
CONSTRUCTOR
構造方法聲明
FIELD
字段聲明(包括枚舉常量)
LOCAL_VARIABLE
局部變量聲明
METHOD
方法聲明
PACKAGE
包聲明
PARAMETER
參數聲明
TYPE
類、接口(包括注釋類型)或枚舉聲明注解的使用限定的例子:@Target(ElementType.METHOD)
public @interface MyAnnotation {String[] value1() default "abc";
}
9、在幫助文檔中加入注解:
要想在制作JavaDoc文件的同時將注解信息加入到API文件中,可以使用java.lang.annotation.Documented。在自定義注解中聲明構建注解文檔:@Documented
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定義注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})public void execute(){System.out.println("method");}
}
10、在注解中使用繼承:
默認情況下注解并不會被繼承到子類中,可以在自定義注解時加上java.lang.annotation.Inherited注解聲明使用繼承。@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Inherited
指示注釋類型被自動繼承。如果在注釋類型聲明中存在 Inherited 元注釋,并且用戶在某一類聲明中查詢該注釋類型,同時該類聲明中沒有此類型的注釋,則將在該類的超類中自動查詢該注釋類型。此過程會重復進行,直到找到此類型的注釋或到達了該類層次結構的頂層 (Object) 為止。如果沒有超類具有該類型的注釋,則查詢將指示當前類沒有這樣的注釋。注意,如果使用注釋類型注釋類以外的任何事物,此元注釋類型都是無效的。還要注意,此元注釋僅促成從超類繼承注釋;對已實現接口的注釋無效。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249498.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249498.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249498.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2018.09.18 while循環

** "loop" 循環 注意要有引號。 **pass 過 #打印 1-100start 1 while start < 101:print("loop",start)start 1 #打印1-49&#xff0c;81-100. 60-80的平方start 1 while start <101 :if start >49 and start < 60:passelif start >5…

2019第二周作業

基礎作業 實驗代碼 #include<stdlib.h> int main(void) {FILE*fp;int num[4],i,b,max;char op;if((fpfopen("c:\\tmj.txt","r"))NULL){ printf("File open error!\n"); exit(0);}for(i0;i<4;i){fscanf(fp,"%d%c",&nu…

實驗一(高見老師收)

學 號201521450016 中國人民公安大學 Chinese people’ public security university 網絡對抗技術 實驗報告 實驗一 網絡偵查與網絡掃描 學生姓名 陳璪琛 年級 2015 區隊 五 指導教師 高見 信息技術與網絡安全學院 2018年9月18日 實驗任務總綱 2018—2019學年…

GitHub筆記(二)——遠程倉庫的操作

二 遠程倉庫 1 創建聯系 第1步&#xff1a;創建SSH Key。在用戶主目錄下&#xff0c;看看有沒有.ssh目錄&#xff0c;如果有&#xff0c;再看看這個目錄下有沒有id_rsa和id_rsa.pub這兩個文件&#xff0c;如果已經有了&#xff0c;可直接跳到下一步。如果沒有&#xff0c;打開S…

QT 子窗體 最大化 界面顯示不對

QT 子窗體 最大化 復原 遇到的問題 項目中有個需求&#xff0c;主窗體中嵌套子窗體&#xff0c;需要將子窗體最大化顯示和復原。 查了很多資料&#xff0c;基本上都是提到&#xff1a;QT中窗口部件QWidget成員函數showFullScreen();是用于將窗口部件全屏顯示&#xff0c;但是他…

Spring 鉤子之BeanFactoryPostProcessor和BeanPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor這兩個接口都是初始化bean時對外暴露的入口之一&#xff0c;和Aware類似&#xff08;PS:關于spring的hook可以看看Spring鉤子方法和鉤子接口的使用詳解講的蠻詳細&#xff09;本文也主要是學習具體的鉤子的細節&#xff0c;以便于實…

什么是HTML DOM對象

HTML DOM 對象 HTML DOM Document 對象 Document 對象 每個載入瀏覽器的 HTML 文檔都會成為 Document 對象。 Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。 提示&#xff1a;Document 對象是 Window 對象的一部分&#xff0c;可通過 window.document 屬…

Python3 matplotlib的繪圖函數subplot()簡介

Python3 matplotlib的繪圖函數subplot()簡介 一、簡介 matplotlib下, 一個 Figure 對象可以包含多個子圖(Axes), 可以使用 subplot() 快速繪制, 其調用形式如下 : subplot(numRows, numCols, plotNum) 圖表的整個繪圖區域被分成 numRows 行和 numCols 列 然后按照從左到右&…

signal(SIGHUP, SIG_IGN);

signal(SIGHUP, SIG_IGN); 的理解轉載于:https://www.cnblogs.com/lanjiangzhou/p/10505653.html

spring鉤子

Spring鉤子方法和鉤子接口的使用詳解 前言 SpringFramework其實具有很高的擴展性&#xff0c;只是很少人喜歡挖掘那些擴展點&#xff0c;而且官方的Refrence也很少提到那些Hook類或Hook接口&#xff0c;至于是不是Spring官方有意為之就不得而知。本文淺析一下筆者目前看到的S…

【bitset 技巧 分塊】bzoj5087: polycomp

神仙zq發現了${n^2\sqrt n}\over 32$做法 Description 你有三個系數為0,1的多項式f(x),g(x),h(x)求f(g(x)) mod h(x)為方便起見&#xff0c;將答案多項式所有系數對2取模輸出即可如果f(x)Sigma(Ak * Xk)則f(g(x))Sigma(Ak(g(x))KInput 一共三行&#xff0c;每行一個多項式,分別…

day 012 生成器 與 列表推導式

生成器的本質就是迭代器&#xff0c;寫法和迭代器不一樣&#xff0c;用法一樣。 獲取方法&#xff1a; 1、通過生成器函數 2、通過各種推導式來實現生成器 3、通過數據的轉換也可以獲取生成器 例如&#xff1a; 更改return 為 yield 即成為生成器 該函數就成為了一個生成器函數…

數據庫設計注意事項和原則

引言數據庫設計是信息系統設計的基礎&#xff0c;一個好的數據庫設計在滿足了軟件需求之外&#xff0c;還要易維護、易擴充等等要求。當然&#xff0c;對專家們反復強調的數據的一致性、冗余性、訪問效率等問題的解決&#xff0c;很大程度上取決于數據庫設計者的經驗和專業水平…

【AtCoder】ARC078

C - Splitting Pile 枚舉從哪里開始分的即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar(\n) #define MAXN 200005 #defi…

20172325 2018-2019-1 《Java程序設計》第二周學習總結

20172325 2018-2019-1 《Java程序設計》第二周學習總結 教材學習內容總結 3.1集合 集合是一種聚集、組織了其他對象的對象。集合可以分為兩大類&#xff1a;線性集合和非線性集合。線性集合&#xff1a;一種其元素按照直線方式組織的集合。非線性集合&#xff1a;一種其元素按某…

數據庫視圖

測試表:user有id&#xff0c;name&#xff0c;age&#xff0c;sex字段 測試表:goods有id&#xff0c;name&#xff0c;price字段 測試表:ug有id&#xff0c;userid&#xff0c;goodsid字段 視圖的作用實在是太強大了&#xff0c;以下是我體驗過的好處&#xff1a; 作用一&…

題解 luogu P2568 GCD

題解 luogu P2568 GCD 時間&#xff1a;2019.3.11 歐拉函數前綴和 題目描述 給定整數\(N\)&#xff0c;求\(1\le x,y \le N\)且\(\gcd(x,y)\)為素數的數對\((x,y)\)有多少對. 分析 枚舉素數\(p\), 先求出\(1\le x,y \le \left \lfloor \dfrac n p \right \rfloor\)且\(\gcd(x, …

解決前后臺發送請求或者接口之間發送請求亂碼的問題

前后臺傳中文亂碼&#xff1a; 前臺使用encodeURI 進行編碼 后臺使用decode進行解碼 如果接口之間調用出現亂碼.接收方是&#xff1f;&#xff1f;&#xff1f;&#xff1f;這種。傳送方式明文的處理方式&#xff1a; 發送方使用decode 進行編碼&#xff1a; 接收方使用的ecod…

MSDN幫助文檔 無法顯示該網頁 的問題解決方案(轉)

MSDN幫助文檔 "無法顯示該網頁" 的問題解決方案 以前就遇到過這樣的問題&#xff0c;還以為是IE7導致的。后來重新安裝了IE7也沒有解決。后來就重新安裝MSDN了&#xff0c;非常郁悶。今天終于知道原因了。因為開了HijackThis刪除了一些注冊協議&#xff0c;然后發現M…

.net Core發布至IIS完全手冊帶各種踩坑

服務器環境配置 和各位大爺報告一下我的服務器環境 : Windows Server 2012 iis 8 小插曲開始: 運維大哥在昨天給了我一臺新的server 0環境開始搭建 。 并且沒有安裝任何的系統補丁。 第一件事情請開始打 補丁 打完補丁之后有時補丁會不完全 ,所以需要去官網獲取補丁: KB2919355…