亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中自定義注解介紹與使用場景詳解

 更新時間:2018年09月04日 16:13:36   作者:JaJian  
最近有所了解到自定義注解的應用,因此學習了一下,下面這篇文章主要給大家介紹了關于Java中自定義注解介紹與使用場景的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧

注解的概念及分類

1.首先我們來看一下什么是注解:

注解就是某種注解類型的一個實例,我們可以用它在某個類上進行標注,這樣編譯器在編譯我們的文件時,會根據(jù)我們自己設定的方法來編譯類。

2.注解的分類

注解大體上分為三種:標記注解,一般注解,元注解,@Override用于標識,該方法是繼承自超類的。這樣,當超類的方法修改后,實現(xiàn)類就可以直接看到了。而@Deprecated注解,則是標識當前方法或者類已經(jīng)不推薦使用,如果用戶還是要使用,會生成編譯的警告。

本文主要介紹的是關于Java自定義注解,下面話不多說了,來一起看看詳細的介紹吧

隨著springboot的流行,以前基于XML的spring配置用的越來越少,JavaConfig形式使用的越來越多,類似于:

@Configuration
public class AppConfig {
 
  @Bean(name="helloBean")
  public HelloWorld helloWorld() {
   return new HelloWorldImpl();
  }
}

可以看出更多的是基于注解(Annotation)實現(xiàn)的,包括springboot的入口類**Application。

@Configuration
@ComponentScan("com.alibaba.trade")
@EnableAutoConfiguration//(exclude = {PageHelperAutoConfiguration.class})
@ServletComponentScan
@EnableTransactionManagement
@EnableDiscoveryClient
@EnableWebMvc
@MapperScan("com.alibaba.trade.shared.mapper")
public class TradeApplication extends SpringBootServletInitializer {
 public static void main(String[] args) {
   SpringApplication.run(TradeApplication.class, args);
 }
}

Java注解不僅讓我們減少了項目中XML文件,方便了維護,同時也使我們代碼更簡潔。那么項目中我們?nèi)绾伍喿x注解以及如何創(chuàng)造自己的注解呢?

注解說明

Java注解又稱Java標注,是Java語言5.0版本開始支持加入源代碼的特殊語法元數(shù)據(jù)。為我們在代碼中添加信息提供了一種形式化的方法,使我們可以在稍后某個時刻非常方便的使用這些數(shù)據(jù)。

Java語言中的類、方法、變量、參數(shù)和包等都可以被標注。和Javadoc不同,Java注解可以通過反射獲取注解內(nèi)容。在編譯器生成類文件時,注解可以被嵌入到字節(jié)碼中。Java虛擬機可以保留注解內(nèi)容,在運行時可以獲取到注解內(nèi)容。

注解本身沒有具體的功能,它相當于一個標注,而這個標注具體的作用和意義需要我們自己實現(xiàn)。一般都是先判斷類或?qū)傩允欠癖辉撟⒔庑揎椩偻ㄟ^反射來獲取注解屬性再實現(xiàn)具體業(yè)務功能。

內(nèi)置注解

Java 定義了一套注解,共有 7 個,3 個在 java.lang 中,剩下 4 個在 java.lang.annotation 中。

1、作用在代碼的注解是

  • @Override - 檢查該方法是否是重載方法。如果發(fā)現(xiàn)其父類,或者是引用的接口中并沒有該方法時,會報編譯錯誤。
  • @Deprecated - 標記過時方法。如果使用該方法,會報編譯警告。
  • @SuppressWarnings - 指示編譯器去忽略注解中聲明的警告。

2、作用在其他注解的注解(或者說元注解)是:

  • @Retention - 標識這個注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運行時可以通過反射訪問。
  • @Documented - 標記這些注解是否包含在用戶文檔中。
  • @Target - 標記這個注解應該是哪種 Java 成員。
  • @Inherited - 標記這個注解是繼承于哪個注解類(默認注解并沒有繼承于任何子類)

3、從 Java 7 開始,額外添加了 3 個注解:

  • @SafeVarargs - Java 7 開始支持,忽略任何使用參數(shù)為泛型變量的方法或構造函數(shù)調(diào)用產(chǎn)生的警告。
  • @FunctionalInterface - Java 8 開始支持,標識一個匿名函數(shù)或函數(shù)式接口。
  • @Repeatable - Java 8 開始支持,標識某注解可以在同一個聲明上使用多次。

元注解

1、@Retention

 @Retention annotation指定標記注釋的存儲方式:

  • RetentionPolicy.SOURCE - 標記的注釋僅保留在源級別中,并由編譯器忽略。
  • RetentionPolicy.CLASS - 標記的注釋在編譯時由編譯器保留,但Java虛擬機(JVM)會忽略。
  • RetentionPolicy.RUNTIME - 標記的注釋由JVM保留,因此運行時環(huán)境可以使用它。

2、@Documented 

 @Documented  注釋表明,無論何時使用指定的注釋,都應使用Javadoc工具記錄這些元素(默認情況下,注釋不包含在Javadoc中)。有關更多信息,請參閱 Javadoc工具頁面。

3、@Target

 @Target  注釋標記另一個注釋,以限制可以應用注釋的Java元素類型。目標注釋指定以下元素類型之一作為其值。

  • ElementType.TYPE 可以應用于類的任何元素。
  • ElementType.FIELD 可以應用于字段或?qū)傩浴?/li>
  • ElementType.METHOD 可以應用于方法級注釋。
  • ElementType.PARAMETER 可以應用于方法的參數(shù)。
  • ElementType.CONSTRUCTOR 可以應用于構造函數(shù)。
  • ElementType.LOCAL_VARIABLE 可以應用于局部變量。
  • ElementType.ANNOTATION_TYPE 可以應用于注釋類型。
  • ElementType.PACKAGE 可以應用于包聲明。
  • ElementType.TYPE_PARAMETER
  • ElementType.TYPE_USE

4、@Inherited 

 @Inherited  注釋表明注釋類型可以從超類繼承。當用戶查詢注釋類型并且該類沒有此類型的注釋時,將查詢類的超類以獲取注釋類型(默認情況下不是這樣)。此注釋僅適用于類聲明。

5、@Repeatable

Repeatable Java SE 8中引入的,@Repeatable注釋表明標記的注釋可以多次應用于相同的聲明或類型使用(即可以重復在同一個類、方法、屬性等上使用)。

自定義注解

Java中自定義注解和創(chuàng)建一個接口相似,自定義注解的格式是以@interface為標志的。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
 
 /**
 * default extension name
 */
 String value() default "";
 
}

我們知道java.lang.annotation包中有一個Annotation的接口,它是所有注解類型擴展的公共接口。那我們是否可以直接通過實現(xiàn)該接口來實現(xiàn)自定義注解呢?

import java.lang.annotation.Annotation;
 
public class MyAnnotation implements Annotation {
 
 @Override
 public Class<? extends Annotation> annotationType() {
 return null;
 }
}

發(fā)現(xiàn)Annotation接口中只有一個annotationType的方法,而且通過Annotation源碼的注釋我們可以發(fā)現(xiàn)答案是不能。

 

漢譯即為:Annotaion被所有注解類型繼承,但是要注意:手動擴展繼承此接口的接口不會定義注解類型。另請注意,此接口本身不定義注解類型。

使用場景

自定義注解的使用場景很多,我們在造輪子寫框架的過程經(jīng)常會使用到,例如我最近就遇到了一個業(yè)務場景:像一些編輯業(yè)務信息的接口,產(chǎn)品要求信息編輯后的新舊值對比,對比的業(yè)務功能,我們的實現(xiàn)方式是拿到前端填寫的Form表單(新值)和數(shù)據(jù)庫中查詢出來的Dto(舊值)通過反射技術獲取到相同屬性字段名,再比較屬性值就可以得出新舊值。得到值之后我們也知道該字段的Dto中的字段名,但是如何將比較得到的新舊值字段的中文名返回給前端呢?例如:

public class Stedent {
 
 private String name;
 
 private int age;
 
 private String sex;
 
 //省略setter,getter
}

比較后我們的結果是 name : “xiaoming “-> “daming”,age : 24 -> 26。但是我們不能直接將name和age返回給前端,他們需要的格式是:姓名: “xiaoming “-> “daming”,年齡 : 24 -> 26。這時候就可以考慮自定義一個注解@FieldName,

@Deprecated
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldName {
 String value() default "";
}

然后將該注解加在屬性字段上面

public class Student {
 
 @FieldName(value = "姓名")
 private String name;
 
 @FieldName(value = "年齡")
 private int age;
 
 @FieldName(value = "性別")
 private String sex;
 
 //省略setter,getter
}

之后就可以通過反射獲取該字段中文名。

// 如果 oldField 屬性值與 newField 屬性值的內(nèi)容不相同
if (!isEmpty(newValue)) {
 Map<String, Object> map = new HashMap<>();
 String newFieldName = newField.getName();
 if (newField.isAnnotationPresent(ApiModelProperty.class)) {
  ApiModelProperty apiModelPropertyAnno = newField.getAnnotation(ApiModelProperty.class);
  newFieldName = apiModelPropertyAnno.value();
 else if (newField.isAnnotationPresent(FieldName.class)) {
  FieldName fieldNameAnno = newField.getAnnotation(FieldName.class);
  newFieldName = fieldNameAnno.name();
 }
  map.put(FIELD_NAME, newFieldName);
  map.put(OLD_VALUE, oldValue);
  map.put(NEW_VALUE, newValue);
  list.add(map);
}

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • java 中RandomAccess接口源碼分析

    java 中RandomAccess接口源碼分析

    這篇文章主要介紹了java 中RandomAccess接口源碼分析的相關資料,需要的朋友可以參考下
    2017-05-05
  • Java實現(xiàn)登錄與注冊頁面

    Java實現(xiàn)登錄與注冊頁面

    這篇文章主要為大家詳細介紹了Java實現(xiàn)登錄與注冊頁面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Java鎖升級的實現(xiàn)過程

    Java鎖升級的實現(xiàn)過程

    這篇文章主要介紹了Java鎖升級的實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • 使用springboot通過spi機制加載mysql驅(qū)動的過程

    使用springboot通過spi機制加載mysql驅(qū)動的過程

    這篇文章主要介紹了使用springboot通過spi機制加載mysql驅(qū)動的過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java如何實現(xiàn)文件壓縮與上傳FTP

    Java如何實現(xiàn)文件壓縮與上傳FTP

    這篇文章主要介紹了Java如何實現(xiàn)文件壓縮與上傳FTP,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 通過Java視角簡單談談局部性原理

    通過Java視角簡單談談局部性原理

    程序的局部性原理是指程序在執(zhí)行時呈現(xiàn)出局部性規(guī)律,即在一段時間內(nèi),整個程序的執(zhí)行僅限于程序中的某一部分,這篇文章主要給大家介紹了關于通過Java視角簡單談談局部性原理的相關資料,需要的朋友可以參考下
    2021-07-07
  • Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目)

    Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目)

    本文主要介紹了Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目),將展示如何設置項目結構、添加依賴關系等,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • spring boot項目fat jar瘦身的實現(xiàn)

    spring boot項目fat jar瘦身的實現(xiàn)

    這篇文章主要介紹了spring boot項目fat jar瘦身的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • SpringBoot整合MOTT動態(tài)讀取數(shù)據(jù)庫連接信息并連接MQTT服務端

    SpringBoot整合MOTT動態(tài)讀取數(shù)據(jù)庫連接信息并連接MQTT服務端

    MQTT是一種輕量級的消息傳輸協(xié)議(Message Queuing Telemetry Transport),旨在實現(xiàn)設備之間的低帶寬和高延遲的通信,本文給大家介紹了SpringBoot整合MOTT動態(tài)讀取數(shù)據(jù)庫連接信息并連接MQTT服務端,需要的朋友可以參考下
    2024-04-04
  • idea新建maven項目沒有src目錄的操作方法

    idea新建maven項目沒有src目錄的操作方法

    這篇文章主要介紹了idea新建maven項目沒有src目錄的兩種操作方法,需要的朋友可以參考下
    2018-03-03

最新評論