日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java工作笔记-注解的进一步理解

發(fā)布時(shí)間:2025/3/15 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java工作笔记-注解的进一步理解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

?

?

基本概念

代碼與實(shí)例


?

基本概念

注解:說明程序,給計(jì)算機(jī)看的。

注釋:給程序員看的。

?

作用分類:

編寫文檔:通過代碼里標(biāo)識的注解生成文檔javadoc(生成doc文檔)

代碼分析:通過代碼里標(biāo)識的注解對代碼進(jìn)行分析(使用反射)

編譯檢查:通過代碼里標(biāo)識的注解人編譯器能夠?qū)崿F(xiàn)基本的編譯檢測(Override)

?

JDK中預(yù)定義的注解:

@Override:檢測被該注釋標(biāo)注的方法是否繼承自父類(接口)

@Deprecated:該注解標(biāo)注的內(nèi)容,已經(jīng)過時(shí)

@SuppressWarnings:壓制警告

?

這里提示下:@SuppressWarnings("all")一般是這么用的

?

代碼與實(shí)例

下面來看下自定義注解,格式如下:

元注解
public @interface 注解名稱{}

注解的本質(zhì),實(shí)際上是接口:

如下代碼:

package demo;public @interface AnnoDemo1 {}

目前先使用javac讓其生成字節(jié)碼文件,再使用javap逆向生成類:

從中可以看到注解的本質(zhì)就是接口.

注解(接口)中的屬性:
? ? ? ? ? 要求:
? ? ? ? ? 1. 屬性的返回值類型:基本數(shù)據(jù)類型、String、枚舉、注解、以上類型的數(shù)組;
? ? ? ? ? 2. 定義了屬性,在使用時(shí)需要給屬性賦值;
? ? ? ? ? ? ?1. 如果定義屬性時(shí),使用default關(guān)鍵字給屬性設(shè)置默認(rèn)值,則使用注解時(shí),可以不進(jìn)行屬性的賦值。
? ? ? ? ? ? ?2. 如果只有一個(gè)屬性需要賦值,并且屬性的名稱是value,則value可以省略,直接定義即可。
? ? ? ? ? ? ?3. 數(shù)組賦值時(shí),值使用{}包裹。如果數(shù)組中只有一個(gè)值,則{}省略

如下代碼:

Person.java

package demo;public enum Person {p1, p2 }

AnnoDemo1.java

package demo;public @interface AnnoDemo1 {int show1();String show2();Person per();AnnoDemo2 anno2();String[] strs();}

AnnoDemo2.java

package demo;public @interface AnnoDemo2 {int age();String name() default "王二麻子";}

Worker.java

package demo;@AnnoDemo1(show1 = 1, show2 = "Hello", per = Person.p1, anno2 = @AnnoDemo2(age = 12), strs = {"1", "2"}) public class Worker { }

下面是關(guān)于元注解相關(guān):

元注解:
? ? ? ? ? @Target:描述注解能夠作用的位置;
? ? ? ? ? ? ? ? ? ? ElementTYpe取值:
? ? ? ? ? ? ? ? ? ? ? ? ?TYPE:可以作用于類上
? ? ? ? ? ? ? ? ? ? ? ? ?METHOD:作用于方法上
? ? ? ? ? ? ? ? ? ? ? ? ?FIELD:用于成員變量
? ? ? ? ? @Retention:描述注解被保留的階段;
? ? ? ? ? ? ? ? ? ? ?@Retention(RetentionPolicy.RUNTIME):保留class字節(jié)碼文件中,并被JVM讀取。
? ? ? ? ? @Decumented:描述注解是否被抽到API文檔中;
? ? ? ? ? @Inherited:描述注解是否被子類繼承。

這里要注意:自定義注解一般使用runtime

后期注解大多數(shù)都是用于替換配置文件的

如下:

AnnoDemo3.java

package demo;import java.lang.annotation.*;@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface AnnoDemo3 {}

注解中:

package demo;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface pro {String className();String methodName(); }

這個(gè)注解,實(shí)際上會生成這樣的字節(jié)碼文件,這個(gè)個(gè)人感覺和Qt中帶有Q_OBJECT和集成了QObject類,生成moc的技術(shù)有異曲同工之妙。

public class ProImpl implements Pro{public String className(){}public String methodName(){} }

?

下面是使用注解來實(shí)現(xiàn)配置文件的加載

如下的例子:

Pro.java

package demo;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Pro {String className();String methodName(); }

MainTest.java

import demo.Pro;import java.lang.reflect.Method;@Pro(className = "demo.Test", methodName = "show") public class MainTest {public static void main(String[] arg) throws Exception{//解析注釋,獲取該類的字節(jié)碼文件對象Class mainTestClass = MainTest.class;//獲取注解對象,內(nèi)存中生成了一個(gè)該注解接口的子類實(shí)例Pro annotation = (Pro) mainTestClass.getAnnotation(Pro.class);//調(diào)用抽象方法,獲取數(shù)據(jù)String s = annotation.className();String s1 = annotation.methodName();//加載該類進(jìn)內(nèi)存Class aClass = Class.forName(s);//創(chuàng)建對象Object o = aClass.newInstance();//獲取方法對象Method method = aClass.getMethod(s1);//執(zhí)行方法method.invoke(o);} }

在程序使用(解析)注解:獲取注解中定義的屬性值:
? ? ?1. 獲取注解定義的位置的對象(Class,Method,Field)
? ? ?2. 獲取指定的注解:
? ? ? ? ? ? getAnnotation(Class)
? ? ?3. 調(diào)用注解中的抽象方法獲取配置的屬性值。

?

下面是一個(gè)綜合案例,通過注解完成,某個(gè)函數(shù)的測試功能。

統(tǒng)計(jì)一個(gè)類中,不拋異常的函數(shù)個(gè)數(shù):

程序運(yùn)行截圖如下:

錯(cuò)誤文件:

源碼如下:

Calculator.java

package demo2;public class Calculator {@Checkpublic void add(){System.out.println("1 + 0 = " + (1 + 0));}@Checkpublic void sub(){System.out.println("1 - 0 = " + (1 - 0));}@Checkpublic void mul(){System.out.println("1 * 0 = " + (1 * 0));}@Checkpublic void div(){System.out.println("1 / 0 = " + (1 / 0));} }

Check.java

package demo2;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Check {}

MainTest2.java

import demo2.Calculator; import demo2.Check;import java.io.BufferedWriter; import java.io.FileWriter; import java.lang.reflect.Method;public class MainTest2 {public static void main(String[] arg) throws Exception{//創(chuàng)建計(jì)算器對象Calculator c = new Calculator();//獲取字節(jié)碼文件對象Class cls = c.getClass();//獲取所有方法Method[] methods = cls.getMethods();int number = 0;//出現(xiàn)異常的此數(shù)BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));for(Method method : methods){//判斷方法上是否有Check注解if(method.isAnnotationPresent(Check.class)){//有就執(zhí)行try{method.invoke(c);}catch (Exception e){//獲取異常,記錄到文件number++;bw.write(method.getName() + "方法出現(xiàn)異常");bw.newLine();bw.write("異常名稱:" + e.getCause().getClass().getSimpleName());bw.newLine();bw.write("異常原因:" + e.getCause().getMessage());bw.newLine();bw.write("------------------------------");}}}bw.newLine();bw.write("本次測試一共出現(xiàn) " + number + " 次異常");bw.flush();bw.close();} }

注解不是程序的一部分,是給編譯器看的,可以理解為注解是一個(gè)標(biāo)簽。

源碼打包下載地址:https://github.com/fengfanchen/Java/tree/master/Annotation

?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Java工作笔记-注解的进一步理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。