国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

java 注解默認值操作

瀏覽:3日期:2022-08-19 10:38:49

我就廢話不多說了,大家還是直接看代碼吧~

package com.zejian.annotationdemo; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; /*** Created by wuzejian on 2017/5/19.* 數據類型使用Demo*/ @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@interface Reference{boolean next() default false;} public @interface AnnotationElementDemo {//枚舉類型enum Status {FIXED,NORMAL}; //聲明枚舉Status status() default Status.FIXED; //布爾類型boolean showSupport() default false; //String類型String name()default ''; //class類型Class<?> testCase() default Void.class; //注解嵌套Reference reference() default @Reference(next=true); //數組類型long[] value();}

補充:Java自定義注解中關于string[] value() default {};的理解

java自定義注解

Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。

注解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annotation 包中。

1、元注解

元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四種。

1.1、@Retention: 定義注解的保留策略

@Retention(RetentionPolicy.SOURCE) //注解僅存在于源碼中,在class字節碼文件中不包含@Retention(RetentionPolicy.CLASS) // 默認的保留策略,注解會在class字節碼文件中存在,但運行時無法獲得,@Retention(RetentionPolicy.RUNTIME) // 注解會在class字節碼文件中存在,在運行時可以通過反射獲取到

注解類:

@Retention(RetentionPolicy.RUNTIME) // 注解會在class字節碼文件中存在,在運行時可以通過反射獲取到@Target({ElementType.FIELD,ElementType.METHOD})//定義注解的作用目標**作用范圍字段、枚舉的常量/方法@Documented//說明該注解將被包含在javadoc中public @interface FieldMeta { /** * 是否為序列號 * @return */ boolean id() default false; /** * 字段名稱 * @return */ String name() default ''; /** * 是否可編輯 * @return */ boolean editable() default true; /** * 是否在列表中顯示 * @return */ boolean summary() default true; /** * 字段描述 * @return */ String description() default ''; /** * 排序字段 * @return */ int order() default 0;}

實體類:

public class Anno { @FieldMeta(id=true,name='序列號',order=1) private int id; @FieldMeta(name='姓名',order=3) private String name; @FieldMeta(name='年齡',order=2) private int age; @FieldMeta(description='描述',order=4) public String desc(){ return 'java反射獲取annotation的測試'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

獲取到注解的幫助類:

public class SortableField { public SortableField(){} public SortableField(FieldMeta meta, Field field) { super(); this.meta = meta; this.field = field; this.name=field.getName(); this.type=field.getType(); } public SortableField(FieldMeta meta, String name, Class<?> type) { super(); this.meta = meta; this.name = name; this.type = type; } private FieldMeta meta; private Field field; private String name; private Class<?> type; public FieldMeta getMeta() { return meta; } public void setMeta(FieldMeta meta) { this.meta = meta; } public Field getField() { return field; } public void setField(Field field) { this.field = field; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Class<?> getType() { return type; } public void setType(Class<?> type) { this.type = type; } }

運行時獲取注解,首先創建一個基類:

public class Parent<T> { private Class<T> entity; public Parent() { init(); } @SuppressWarnings('unchecked') public List<SortableField> init(){ List<SortableField> list = new ArrayList<SortableField>(); /**getClass().getGenericSuperclass()返回表示此 Class 所表示的實體(類、接口、基本類型或 void) * 的直接超類的 Type(Class<T>泛型中的類型),然后將其轉換ParameterizedType。。 * getActualTypeArguments()返回表示此類型實際類型參數的 Type 對象的數組。 * [0]就是這個數組中第一個了。。 * 簡而言之就是獲得超類的泛型參數的實際類型。。*/ entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0];// FieldMeta filed = entity.getAnnotation(FieldMeta.class); if(this.entity!=null){ /**返回類中所有字段,包括公共、保護、默認(包)訪問和私有字段,但不包括繼承的字段 * entity.getFields();只返回對象所表示的類或接口的所有可訪問公共字段 * 在class中getDeclared**()方法返回的都是所有訪問權限的字段、方法等; * 可看API * */ Field[] fields = entity.getDeclaredFields();// for(Field f : fields){ //獲取字段中包含fieldMeta的注解 FieldMeta meta = f.getAnnotation(FieldMeta.class); if(meta!=null){ SortableField sf = new SortableField(meta, f); list.add(sf); } } //返回對象所表示的類或接口的所有可訪問公共方法 Method[] methods = entity.getMethods(); for(Method m:methods){ FieldMeta meta = m.getAnnotation(FieldMeta.class); if(meta!=null){ SortableField sf = new SortableField(meta,m.getName(),m.getReturnType()); list.add(sf); } } //這種方法是新建FieldSortCom類實現Comparator接口,來重寫compare方法實現排序// Collections.sort(list, new FieldSortCom()); Collections.sort(list, new Comparator<SortableField>() { @Override public int compare(SortableField s1,SortableField s2) { return s1.getMeta().order()-s2.getMeta().order();// return s1.getName().compareTo(s2.getName());//也可以用compare來比較 } }); } return list; }}

創建子類繼承基類:

public class Child extends Parent<Anno>{ }

測試類:

public class TestAnnotation { @SuppressWarnings({ 'unchecked', 'rawtypes' }) public static void main(String[] args) { Parent c = new Child(); List<SortableField> list = c.init();//獲取泛型中類里面的注解 //輸出結果 for(SortableField l : list){ System.out.println('字段名稱:'+l.getName()+'t字段類型:'+l.getType()+ 't注解名稱:'+l.getMeta().name()+'t注解描述:'+l.getMeta().description()); } }}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; } @Override public 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; } @Deprecated public 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 { @MyAnnotation public 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.5

getAnnotation

<T extends Annotation> T getAnnotation(Class<T> annotationClass)

如果存在該元素的指定類型的注釋,則返回這些注釋,否則返回 null。

參數:

annotationClass - 對應于注釋類型的 Class 對象

返回:

如果該元素的指定注釋類型的注釋存在于此對象上,則返回這些注釋,否則返回 null

拋出:

NullPointerException - 如果給定的注釋類為 null

從以下版本開始:

1.5

getAnnotations

Annotation[] getAnnotations()

返回此元素上存在的所有注釋。(如果此元素沒有注釋,則返回長度為零的數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。

返回:

此元素上存在的所有注釋

從以下版本開始:

1.5

getDeclaredAnnotations

Annotation[] getDeclaredAnnotations()

返回直接存在于此元素上的所有注釋。與此接口中的其他方法不同,該方法將忽略繼承的注釋。(如果沒有注釋直接存在于此元素上,則返回長度為零的一個數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。

返回:

直接存在于此元素上的所有注釋

從以下版本開始:

1.5

下面是使用反射讀取RUNTIME保留策略的Annotation信息的例子:

自定義注解:

@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation { String[] value1() default 'abc';}

使用自定義注解:

public class AnnotationTest2 { @MyAnnotation(value1={'a','b'}) @Deprecated public 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[]{}); //獲取myAnnotation String[] 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 ElementTypeextends 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。

在自定義注解中聲明構建注解文檔:

@Documentedpublic @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) 為止。如果沒有超類具有該類型的注釋,則查詢將指示當前類沒有這樣的注釋。

注意,如果使用注釋類型注釋類以外的任何事物,此元注釋類型都是無效的。還要注意,此元注釋僅促成從超類繼承注釋;對已實現接口的注釋無效。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。如有錯誤或未考慮完全的地方,望不吝賜教。

標簽: Java
相關文章:
主站蜘蛛池模板: 久久精品视频观看 | 性欧美欧美巨大69 | 欧美性视频一区二区三区 | 三级视频中文字幕 | 欧美国产合集在线视频 | 国产在线观看91精品一区 | 一区二区三区在线 | 网站 | 河边性xxxxfreexxxxx | 国内精品久久久久影院老司 | 国产在线步兵一区二区三区 | 99精品这里只有精品高清视频 | 一区三区三区不卡 | 2019在线亚洲成年视频网站 | 亚洲国产成a人v在线观看 | 456主播喷水在线观看 | 成人免费午夜视频 | 久久6视频 | 免看一级一片一在线看 | 久久精品免观看国产成人 | 亚洲一级片在线播放 | 久久亚洲国产欧洲精品一 | 美女黄色免费在线观看 | 久久精品国内一区二区三区 | 手机亚洲第一页 | 亚洲福利影院 | 九九九九精品视频在线播放 | 久久视频6免费观看视频精品 | 欧美jizzhd极品欧美 | 亚洲欧美7777| 精品免费久久久久国产一区 | 亚洲日本高清影院毛片 | 欧美在线二区 | 久久久久久中文字幕 | 精品国产91在线网 | 久久伊人精品热在75 | 欧美一区综合 | 日本一区二区三区高清福利视频 | 欧美日韩中文国产一区二区三区 | 亚洲精品字幕一区二区三区 | 日韩经典视频 | 日韩一级大片 |