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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 注解详解 (annotation)

發布時間:2025/3/21 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 注解详解 (annotation) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是java注解

注解是java5的新特性。注解可以看做一種注釋或者元數據(MetaData),可以把它插入到我們的java代碼中,用來描述我們的java類,從而影響java類的行為。

Java注解的目的

使用Java注解一般來說主要有三種目的

  • 構建時指示: RetentionPolicy.SOURCE
  • 編譯期指示: RetentionPolicy.CLASS
  • 運行時指示: RetentionPolicy.RUNTIME

Java注解可以用在構建期。當構建我們的工程時,構建進程會編譯源碼、生成xml文件,打包編譯后的代碼和文件到jar包。構建過程一般由構建工具自動完成,常用的構建工具有ant、maven。構建工具在構建時會自動掃描我們的代碼,當遇到構建期注解時,會根據注解的內容生成源碼或者其它文件。

注解基本概念

注解的構成

一個java注解由一個@符后面跟一個字符串構成,類似于這樣:

@Entity

java注解中一般包含一些元素,這些元素類似于屬性或者參數,可以用來設置值,比如我們有一個包含兩個元素的@Entity注解:

@Entity(tableName = "vehicles", primaryKey = "id")

上面注解中有兩個元素,tableName和primaryKey,它們各自都被賦予了自己的元素值。

注解的位置

注解可以用于描述一個類、接口、方法、方法參數、字段、局部變量等。在下邊這個例子中,注解分別用在了類、字段、方法、參數和局部變量中:

//注解一個類 @Entity public class Vehicle {//注解一個字段@Persistentprotected String vehicleName = null;//注解一個方法@Getterpublic String getVehicleName() {return this.vehicleName;}//注解一個參數public void setVehicleName(@Optional vehicleName) {this.vehicleName = vehicleName;}public List addVehicleNameToList(List names) {//注解一個局部變量@OptionalList localNames = names;if(localNames == null) {localNames = new ArrayList();}localNames.add(getVehicleName());return localNames;} }

一些常用的內置注解

Java本身提供了三個內置注解,他們分別是:

1. @Deprecated 2. @Override 3. @SuppressWarnings

@Deprecated注解

@Deprecated可以用來描述一個類、方法或者字段,表示java不贊成使用這些被描述的對象,如果我們使用了這些類、方法或者字段,編譯器會給我們警告。@Deprecated注解使用方法如下:

@Deprecated public class MyComponent { }

在我們實際應用中,在使用@Deprecated注解時,最好同時使用Java Doc的@deprecated符號,用來描述當前類、方法或者字段是不贊成使用的,并且告訴開發者應該用哪個對象替換,如下面例子:

@Deprecated /**@deprecated Use MyNewComponent instead. */ public class MyComponent {}

@Override注解

@Override注解是一個編譯時注解,它主要用在一個子類的方法中,當被注解的子類的方法在父類中找不到與之匹配的方法時,編譯器會報錯。 當我們在子類中覆蓋父類的方法時,就要用到@Override注解,這樣,如果父類中的方法名稱或參數發生改變時,如果子類沒有做相應的調整編譯器便會報錯,這就是@Override注解所起到的作用。當然@Override注解不是強制使用的,但我還是推薦大家盡量使用它。下面是一個@Override注解的例子:

public class MySuperClass {public void doTheThing() {System.out.println("Do the thing");} }public class MySubClass extends MySuperClass{@Overridepublic void doTheThing() {System.out.println("Do it differently");} }

@SuppressWarnings

@SuppressWarnings注解的作用是使編譯器忽略掉編譯器警告。比如,如果我們的一個方法調用了一個@Deprecated方法,或者做了一個不安全的類型轉換,此時編譯器會生成一個警告。如果我們不想看到這些警告,我們就可以使用@SuppressWarnings注解忽略掉這些警告:

@SuppressWarnings public void methodWithWarning() {}

創建自定義注解

定義一個自定義注解

從上面內置注解可以看到,注解很方便也很有用,很多時候我們也需要創建我們自己的注解。創建注解其實和創建類或接口一樣簡單:

@interface MyAnnotation {String value();String name();int age();String[] newNames(); }

上面代碼便創建了一個@MyApplication注解,它一共有四個元素。@interface關鍵字就代表這是一個注解類型,所以使用@interface關鍵字就可以創建注解了。

需要注意的是,注解中的每個元素定義類似于接口中的方法定義。每個元素定義包含一個數據類型名稱,注解元素的數據類型可以是java基本數據類型、String、數組,但不能是復雜對象類型。

下面這段代碼演示了如何使用注解:

@MyAnnotation(value="123",name="Jakob",age=37,newNames={"Jenkov", "Peterson"} ) public class MyClass {}

給注解元素設置默認值

我們可以通過default關鍵字為某個元素設置默認值,當一個元素被設置默認值之后,這個元素便成了注解的可選元素。?
下面我們為@MyAnnotation注解的value元素設置一個默認值:

@interface MyAnnotation {String value() default "";String name();int age();String[] newNames(); }

當value元素設置默認值之后,再使用時我們就可以省略掉value元素,此時的value值采用的是默認值:

@MyAnnotation(name="Jakob",age=37,newNames={"Jenkov", "Peterson"} ) public class MyClass {}

兩個元注解:@Retention和@Target

元注解就是注解的注解。我們可以通過元注解來控制描述我們自定義注解的行為。

@Retention

@Retention用來定義當前注解的作用范圍,如果我們要把我們的自定義注解限制為運行時有效,那么我們可以使用@Retention注解進行指定:

import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation {String value() default "";}

注意@MyAnnotation注解上面的@Retention的值:

@Retention(RetentionPolicy.RUNTIME)

上面這個注解會告訴編譯器和JVM,這個注解需要在運行時有效,JVM會在運行時通過反射機制獲取注解信息,關于如何在運行時利用反射獲取注解信息,最后面會進行介紹。@Retention注解的值一共有三種:

  • RetentionPolicy.SOURCE :?注解只存在于源碼中,不會存在于.class文件中,在編譯時會被忽略掉
  • RetentionPolicy.CLASS:注解只存在于.class文件中,在編譯期有效,但是在運行期會被忽略掉,這也是默認范圍
  • RetentionPolicy.RUNTIME:在運行期有效,JVM在運行期通過反射獲得注解信息

@Target

@Target注解用來約束自定義注解可以注解Java的哪些元素。比如下面這個例子:

import java.lang.annotation.ElementType; import java.lang.annotation.Target;@Target({ElementType.METHOD}) public @interface MyAnnotation {String value(); }

這個例子中,@Target的值是ElementType.METHOD,通過它的名稱可以看出,這個自定義注解只能注解類的方法。

ElementType的值一共有以下幾種:

  • ElementType.ANNOTATION_TYPE
  • ElementType.CONSTRUCTOR
  • ElementType.FIELD
  • ElementType.LOCAL_VARIABLE
  • ElementType.METHOD
  • ElementType.PACKAGE
  • ElementType.PARAMETER
  • ElementType.TYPE

其中大部分通過名字就能看出它的作用,不過有兩個需要單獨介紹一下:

  • ElementType.ANNOTATION_TYPE:元注解類型,只能用來注解其它的注解,例如@Target和@Retention。
  • ElementType.TYPE:可以用來注解任何類型的java類,如類、接口、枚舉、或者注解類。

@Inherited

@Inherited注解表示當前注解會被注解類的子類繼承。比如有一個自定義注解:

java.lang.annotation.Inherited@Inherited public @interface MyAnnotation {}

如果有一個類使用了上面這個注解:

@MyAnnotation public class MySuperClass { ... }

那么這個類的子類也會繼承這個注解:

public class MySubClass extends MySuperClass { ... }

因為MySubClass?繼承了MyClass,而MyClass的注解@MyAnnotation是可繼承的,最終MySubClass也會有@MyAnnotation注解。

@Documented

@Documented的作用是告訴JavaDoc工具,當前注解本身也要顯示在Java Doc中。比如我們用@Document注解了我們的自定義注解:

import java.lang.annotation.Documented;@Documented public @interface MyAnnotation {}

如果一個類使用了這個注解:

@MyAnnotation public class MySuperClass { ... }

那么當生成MySuperClass的JavaDoc的時候,@MyAnnotation也會出現在JavaDoc當中。

通過反射獲得Java注解信息

上面對注解做了一個詳細介紹,具體該如何使用我們的自定義注解呢?其實在現實應用中,我們的自定義注解一般都是起到運行時指示的作用,也就是運行時注解。對于運行時注解,我們可以通過反射機制獲得注解信息。

比如我們有一個自定義注解:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation {public String name();public String value(); }

并用這個注解注解了一個類:

@MyAnnotation(name = "hello name",value = "hello value") public class MyClass {}

獲取類的注解信息

public class TestAnnotation {public static void main(String[] args) {//通過反射獲得MyClass的注解信息MyAnnotation myAnnotation=MyClass.class.getAnnotation(MyAnnotation.class);System.out.println(myAnnotation.name());System.out.println(myAnnotation.value());} }

獲取方法的注解信息

public class TestAnnotation {public static void main(String[] args) {Method method = null;try {method = MyClassB.class.getMethod("method");Annotation annotation = method.getAnnotation(MyAnnotation.class);if (annotation !=null) {MyAnnotation myAnnotation = (MyAnnotation) annotation;System.out.println("name: " + myAnnotation.name());System.out.println("value: " + myAnnotation.value());}} catch (NoSuchMethodException e) {e.printStackTrace();}} }

獲取參數的注解信息

Method method = ... //obtain method object Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Class[] parameterTypes = method.getParameterTypes();int i=0; for(Annotation[] annotations : parameterAnnotations){Class parameterType = parameterTypes[i++];for(Annotation annotation : annotations){if(annotation instanceof MyAnnotation){MyAnnotation myAnnotation = (MyAnnotation) annotation;System.out.println("param: " + parameterType.getName());System.out.println("name : " + myAnnotation.name());System.out.println("value: " + myAnnotation.value());}} }

獲取字段的注解信息

Field field = ... // obtain method object Annotation annotation = field.getAnnotation(MyAnnotation.class);if(annotation instanceof MyAnnotation){MyAnnotation myAnnotation = (MyAnnotation) annotation;System.out.println("name: " + myAnnotation.name());System.out.println("value: " + myAnnotation.value()); } from: https://yq.aliyun.com/articles/65139?spm=5176.100239.blogcont61791.36.xwqy99

總結

以上是生活随笔為你收集整理的Java 注解详解 (annotation)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。