最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的注解詳解(Annotation)

 更新時(shí)間:2025年03月04日 09:41:32   作者:小寶945  
文章介紹了Java中的注解,包括注解的定義、元注解、Java內(nèi)置的三大注解、自定義注解、反射注解以及注解的作用,注解是一種特殊的標(biāo)記,可以用于類、方法、字段等元素,用于提供元數(shù)據(jù)信息

所有的注解類型都繼承自 java.lang.annotation.Annotation 接口。

注解(Annotation)是一種引用數(shù)據(jù)類型。編譯之后也是生成 xxx.class 文件。

一個(gè)注解準(zhǔn)確意義上來(lái)說(shuō),只不過(guò)是一種特殊的注釋而已,如果沒有解析它的代碼,它可能連注釋都不如。

解析一個(gè)類或者方法的注解往往有兩種形式

一種是編譯期直接的掃描。=====> @Retention(RetentionPolicy.SOURCE)

  • 編譯器的掃描指的是編譯器在對(duì) java 代碼編譯字節(jié)碼的過(guò)程中會(huì)檢測(cè)到某個(gè)類或者方法被一些注解修飾,這時(shí)它就會(huì)對(duì)于這些注解進(jìn)行某些處理。典型的就是 @Override 注解。
  • 這一種情況只適用于那些編譯器已經(jīng)熟知的注解類,比如 JDK 內(nèi)置的幾個(gè)注解,而你自定義的注解,編譯器是不知道你這個(gè)注解的作用的,當(dāng)然也不知道該如何處理,往往只是會(huì)根據(jù)該注解的作用范圍來(lái)選擇是否編譯進(jìn)字節(jié)碼文件,僅此而已。

一種是運(yùn)行期反射。====> @Retention(RetentionPolicy.RUNTIME)

一、元注解

  • 元注解是用于修飾注解的注解,通常用在注解的定義上。
  • 元注解一般用于指定某個(gè)注解生命周期以及作用目標(biāo)等信息。

Java 中的元注解

@Target:注解的作用目標(biāo)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
	/**
 	* Returns an array of the kinds of elements an annotation interface
 	* can be applied to.
 	* @return an array of the kinds of elements an annotation interface
 	* can be applied to
 	*/
	ElementType[] value();
}
  • ElementType.TYPE:允許被修飾的注解作用在類、接口和枚舉上
  • ElementType.FIELD:允許作用在屬性字段上
  • ElementType.METHOD:允許作用在方法上
  • ElementType.PARAMETER:允許作用在方法參數(shù)上
  • ElementType.CONSTRUCTOR:允許作用在構(gòu)造器上
  • ElementType.LOCAL_VARIABLE:允許作用在本地局部變量上
  • ElementType.ANNOTATION_TYPE:允許作用在注解上
  • ElementType.PACKAGE:允許作用在包上

@Retention:注解的生命周期

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
   /**
 	* Returns the retention policy.
  	* @return the retention policy
	*/
	RetentionPolicy value();
}
  • RetentionPolicy.SOURCE:當(dāng)前注解編譯期可見,不會(huì)寫入 class 文件
  • RetentionPolicy.CLASS:類加載階段丟棄,會(huì)寫入 class 文件
  • RetentionPolicy.RUNTIME:永久保存,可以反射獲取

@Documented:注解是否應(yīng)當(dāng)被包含在 JavaDoc 文檔中

@Inherited:是否允許子類繼承該注解

二、Java 中內(nèi)置的三大注解

  • @Override
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

它沒有任何的屬性,所以并不能存儲(chǔ)任何其他信息。它只能作用于方法之上,編譯結(jié)束后將被丟棄。

僅被編譯器可知,編譯器在對(duì) java 文件進(jìn)行編譯成字節(jié)碼的過(guò)程中,一旦檢測(cè)到某個(gè)方法上被修飾了該注解,就會(huì)去匹對(duì)父類中是否具有一個(gè)同樣方法簽名的函數(shù),如果不是,自然不能通過(guò)編譯。

  • @Deprecated
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
    String since() default "";
    boolean forRemoval() default false;
}

可以修飾所有的類型,作用是,標(biāo)記當(dāng)前的類或者方法或者字段等已經(jīng)不再被推薦使用了,可能下一次的 JDK 版本就會(huì)刪除。

  • @SuppressWarnings

三、自定義注解

語(yǔ)法格式:

[修飾符列表] @interface 注解類型名{
	類型 屬性() [defauult 值];
}
// 樣例
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String name() default "gdb";
    String[] phoneNumbers() default {};
}

注解當(dāng)中的屬性類型可以是:byte short int long float double boolean char String Class 枚舉類型以及以上每一種的數(shù)組形式。

四、反射注解

要求必須使用 @Retention(RetentionPolicy.RUNTIME),這樣該注解才能夠被反射到。

例子:反射類上的 @MyAnnotation 注解。

  • 1.編寫自己的注解:
package annotation1;

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 MyAnnotation {
    String name() default "gdb";
    String[] phoneNumbers() default {};
}	
  • 2.在類上使用自己的注解:
package annotation1;

@MyAnnotation(name = "zhangsan", phoneNumbers = {"123456", "654321"})
public class MyAnnotationTest {

}
  • 3.通過(guò)反射機(jī)制來(lái)獲取指定類上的注解信息:
package annotation1;

import java.util.Arrays;

public class ReflectAnnotation {
    public static void main(String[] args) throws Exception {
        //獲取類
        Class<?> c = Class.forName("annotation1.MyAnnotationTest");
        //判斷類上面是否有 @MyAnnotation
        if (c.isAnnotationPresent(MyAnnotation.class)){
            //獲取注解對(duì)象
            MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);
            //獲取注解對(duì)象的屬性和調(diào)用接口沒有區(qū)別
            System.out.println(myAnnotation.name() + ", " + Arrays.toString(myAnnotation.phoneNumbers()));
        }
        //判斷 Date 類上面是否有 @MyAnnotation 這個(gè)注解。
        Class<?> s = Class.forName("java.lang.String");
        System.out.println(s.isAnnotationPresent(MyAnnotation.class));
    }
}

五、注解的作用

注解在程序當(dāng)中等同于一種標(biāo)記,如果這個(gè)元素上有這個(gè)注解怎么辦,沒有這個(gè)注解怎么辦。

應(yīng)用場(chǎng)景:假設(shè)有這樣一個(gè)注解,叫做 @Id,這個(gè)注解只能出現(xiàn)在類上面,當(dāng)這個(gè)類上有這個(gè)注解的時(shí)候,要求這個(gè)類中必須有一個(gè) int 類型的 id 屬性。如果沒有這個(gè)屬性就報(bào)異常。如果有這個(gè)屬性就正常執(zhí)行。

  • 1.編寫 @Id 注解:
package annotation1;

public class NotHasIdException extends RuntimeException{
    public NotHasIdException() {
    }

    public NotHasIdException(String message) {
        super(message);
    }
}
  • 2.編寫異常類:
package annotation1;

public class NotHasIdException extends RuntimeException{
    public NotHasIdException() {
    }

    public NotHasIdException(String message) {
        super(message);
    }
}
  • 3.編寫使用 @Id 注解的類:
package annotation1;

@Id
public class IdAnnotationTest {
    int id;
}
  • 4.通過(guò)反射機(jī)制來(lái)判斷是否正確:
package annotation1;

import java.lang.reflect.Field;

public class ReflectAnnotation {
    public static void main(String[] args) throws Exception {
        //獲取類
        Class<?> c = Class.forName("annotation1.IdAnnotationTest");
        //判斷類上面是否有 @Id 注解
        if (c.isAnnotationPresent(Id.class)){
            //當(dāng)一個(gè)類上面有 @Id 注解的時(shí)候,要求類中必須存在 int 類型的id屬性。
            //如果沒有int類型的id屬性則報(bào)異常。
            //獲取類的所有屬性
            Field[] fields = c.getDeclaredFields();
            boolean isOK = false;
            for(Field field : fields){
                if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
                    isOK = true;
                    break;
                }
            }
            //判斷是否合法
            if (!isOK)
                throw new NotHasIdException("被@Id注解標(biāo)注的類沒有int類型的id屬性!??!");
        }
    }
}

六、總結(jié)

  • 如果一個(gè)注解的屬性的名字是 value,并且只有一個(gè)屬性的話,在使用的時(shí)候,該屬性名可以省略。
  • 如果屬性是一個(gè)數(shù)組,如果數(shù)組中只有一個(gè)元素,大括號(hào)可以省略。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

原阳县| 岑巩县| 岳阳县| 莱阳市| 柯坪县| 淮安市| 锦州市| 怀来县| 祁连县| 托克托县| 湘阴县| 方城县| 黎平县| 祁阳县| 齐河县| 建湖县| 通州区| 监利县| 阳山县| 宜城市| 浑源县| 天门市| 麟游县| 宣化县| 正阳县| 库伦旗| 开平市| 泰兴市| 乳山市| 平安县| 临潭县| 明星| 南乐县| 梁山县| 聂拉木县| 秦皇岛市| 石家庄市| 长乐市| 南通市| 牡丹江市| 神池县|