欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java-Java5.0注解全面解讀

 更新時(shí)間:2021年07月19日 11:13:26   作者:小小工匠  
這篇文章主要介紹了Java-Java5.0注解全面解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

概述

Java5.0注解可以看做Javadoc和Xdoclet標(biāo)簽的延伸和發(fā)展,在Java5.0中可以自定義這些標(biāo)簽,并通過(guò)Java語(yǔ)言的反射機(jī)制獲取類(lèi)中標(biāo)注的注解,完成特定的功能。

注解是代碼的附屬信息,它遵循一個(gè)基本的原則:注解不能直接干擾程序代碼的運(yùn)行,無(wú)論增加或者刪除注解,代碼都能正常運(yùn)行。

Java語(yǔ)言解釋器會(huì)忽略這些注解,而由第三方工具負(fù)責(zé)對(duì)注解進(jìn)行處理。 第三方工具可以利用代碼中的注解間接控制程序代碼的運(yùn)行,它們通過(guò)Java反射機(jī)制讀取注解的信息,并根據(jù)這些信息更改目標(biāo)程序的邏輯。

元注解Meta-annotation

元注解的作用就是負(fù)責(zé)注解其他注解。

Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類(lèi)型,它們被用來(lái)提供對(duì)其它 annotation類(lèi)型作說(shuō)明。

Java5.0定義的元注解: 

  • - @Target
  • - @Retention
  • - @Documented
  • - @Inherited

這幾個(gè)類(lèi)都在java.lang.annotation包中

@Target

@Target主要說(shuō)明Annotation所修飾的對(duì)象范圍。

Annotation可被用于 packages、types(類(lèi)、接口、枚舉、Annotation類(lèi)型)、類(lèi)型成員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch參數(shù))。

在A(yíng)nnotation類(lèi)型的聲明中使用了target可更加明晰其修飾的目標(biāo)。

作用:用于描述注解的使用范圍,即被描述的注解可以用在什么地方。

取值(ElementType)有: @Target(ElementType.XXX)取值如下

  • - TYPE:類(lèi)、接口、注解類(lèi)、Enum聲明處,相應(yīng)的注解稱(chēng)為類(lèi)型注解
  • - FIELD:類(lèi)成員變量或者常量聲明處,相應(yīng)的注解被稱(chēng)為域值注解
  • - METHOD:方法處聲明,相應(yīng)的注解稱(chēng)為方法注解
  • - PARAMETER:參數(shù)聲明處,相應(yīng)的注解稱(chēng)為參數(shù)注解
  • - CONSTRUCTOR:構(gòu)造函數(shù)聲明處,相應(yīng)的注解稱(chēng)為構(gòu)造函數(shù)注解
  • - LOCAL_VARIABLE:局部變量聲明處,相應(yīng)的注解稱(chēng)為局域比納涼注解
  • - PACKAGE:包聲明處,相應(yīng)的注解被稱(chēng)為包注解

舉例:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 *
 * @Description: 注解@DataSource既可以加在方法上,也可以加在接口或者接口的實(shí)現(xiàn)類(lèi)上
 *              
 * 
 * @author: Mr.Yang
 * @date: 2017年7月24日 下午9:59:29
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    // 和配置文件中 dynamicDatasourceMap中的key保持一致
    public static String PR_RB = "dataSourcePR";
    public static String DR_RB = "dataSourceDR";
    public static String PR_CC = "dataSourceCC";
    /**
     * 
     * 
     * @Title: name
     * 
     * @Description: 如果僅標(biāo)注@DataSource 默認(rèn)為PR_RB數(shù)據(jù)庫(kù)實(shí)例
     * 
     * @return
     * 
     * @return: String
     */
    String name() default DataSource.PR_RB;
}

@Retention

@Retention定義了該Annotation被保留的時(shí)間長(zhǎng)短.

某些Annotation僅出現(xiàn)在源代碼中,而被編譯器丟棄;

而另一些卻被編譯在class文件中,編譯在class文件中的Annotation可能會(huì)被虛擬機(jī)忽略,

而另一些在class被裝載時(shí)將被讀?。ú⒉挥绊慶lass的執(zhí)行,因?yàn)锳nnotation與class在使用上是被分離的)。

使用這個(gè)meta-Annotation可以對(duì) Annotation的“生命周期”限制。

作用:表示需要在什么級(jí)別保存該注釋信息,用于描述注解的生命周期(即被描述的注解在什么范圍內(nèi)有效)

Retention meta-annotation類(lèi)型有唯一的value作為成員,它的取值來(lái)自java.lang.annotation.RetentionPolicy的枚舉類(lèi)型值。

這里寫(xiě)圖片描述

取值(RetentionPoicy)有:

  • SOURCE:在源文件中有效(即源文件保留),單對(duì)應(yīng)的字節(jié)碼文件將不再保留
  • CLASS:在class文件中有效(即class保留),但類(lèi)家愛(ài)妻加載字節(jié)碼文件時(shí)不會(huì)將注解加載到JVM中,即運(yùn)行期不能獲取注解信息
  • RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留),注解信息在目標(biāo)類(lèi)加載到JVM后依然保留,在運(yùn)行期可以通過(guò)反射機(jī)制讀取類(lèi)中的注解信息

比如

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    .......
}

@Documented

@Documented用于描述其它類(lèi)型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API,因此可以被例如javadoc此類(lèi)的工具文檔化。Documented是一個(gè)標(biāo)記注解,沒(méi)有成員。

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    .......
}

@Inherited

@Inherited 元注解是一個(gè)標(biāo)記注解,@Inherited闡述了某個(gè)被標(biāo)注的類(lèi)型是被繼承的。如果一個(gè)使用了@Inherited修飾的annotation類(lèi)型被用于一個(gè)class,則這個(gè)annotation將被用于該class的子類(lèi)。

@Inherited annotation類(lèi)型是被標(biāo)注過(guò)的class的子類(lèi)所繼承。類(lèi)并不從它所實(shí)現(xiàn)的接口繼承annotation,方法并不從它所重載的方法繼承annotation。

當(dāng)@Inherited annotation類(lèi)型標(biāo)注的annotation的Retention是RetentionPolicy.RUNTIME,則反射API增強(qiáng)了這種繼承性。如果我們使用java.lang.reflect去查詢(xún)一個(gè)@Inherited annotation類(lèi)型的annotation時(shí),反射代碼檢查將展開(kāi)工作:檢查class和其父類(lèi),直到發(fā)現(xiàn)指定的annotation類(lèi)型被發(fā)現(xiàn),或者到達(dá)類(lèi)繼承結(jié)構(gòu)的頂層。

自定義注解

使用@interface自定義注解時(shí),自動(dòng)繼承了java.lang.annotation.Annotation接口,由編譯程序自動(dòng)完成其他細(xì)節(jié)。

在定義注解時(shí),不能繼承其他的注解或接口。

@interface用來(lái)聲明一個(gè)注解,其中的每一個(gè)方法實(shí)際上是聲明了一個(gè)配置參數(shù)。

方法的名稱(chēng)就是參數(shù)的名稱(chēng),返回值類(lèi)型就是參數(shù)的類(lèi)型(返回值類(lèi)型只能是基本類(lèi)型、Class、String、enum)。

可以通過(guò)default來(lái)聲明參數(shù)的默認(rèn)值。

定義注解格式:

 public @interface 注解名 {定義體}

注解參數(shù)的可支持?jǐn)?shù)據(jù)類(lèi)型

所有基本數(shù)據(jù)類(lèi)型(int,float,boolean,byte,double,char,long,short)

  • String類(lèi)型
  • Class類(lèi)型
  • enum類(lèi)型
  • Annotation類(lèi)型
  • 以上所有類(lèi)型的數(shù)組

Annotation類(lèi)型里面的參數(shù)設(shè)定規(guī)則:

第一,只能用public或默認(rèn)(default)這兩個(gè)訪(fǎng)問(wèn)權(quán)修飾.例如,String value();這里把方法設(shè)為defaul默認(rèn)類(lèi)型;   

第二,參數(shù)成員只能用基本類(lèi)型byte,short,char,int,long,float,double,boolean八種基本數(shù)據(jù)類(lèi)型和 String,Enum,Class,annotations等數(shù)據(jù)類(lèi)型,以及這一些類(lèi)型的數(shù)組.例如,String value();這里的參數(shù)成員就為String;  

第三,如果只有一個(gè)參數(shù)成員,最好把參數(shù)名稱(chēng)設(shè)為”value”,后加小括號(hào).

實(shí)例

代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster

通常情況下,第三方工具不但負(fù)責(zé)處理特定的注解,其本身還提供了這些注解的定義。 事實(shí)上,定義注解類(lèi)本身并不困難,Java提供了定義注解的語(yǔ)法,如上所述。

編寫(xiě)注解類(lèi)

我們著手來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的注解類(lèi)

package com.xgj.aop.spring.advisor.anno;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 
 * 
 * @ClassName: NeedTest
 * 
 * @Description: 自定義注解
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年8月23日 下午4:50:11
 */
// 聲明注解的保留期限
@Retention(RetentionPolicy.RUNTIME)
// 聲明可以使用該注解的目標(biāo)類(lèi)型
@Target(ElementType.METHOD)
// 可以被javadoc此類(lèi)的工具文檔化
@Documented
public @interface NeedTestAnnotation { // 定義注解
    // 聲明注解成員
    boolean value() default false;
}

Java新語(yǔ)法規(guī)定使用@interface修飾符定義注解類(lèi),一個(gè)注解可以擁有多個(gè)成員,成員聲明和接口方法聲明類(lèi)似,這里僅僅定義了一個(gè)成員。

成員聲明以下幾點(diǎn)限制:

  • 成員以無(wú)入?yún)?,無(wú)拋出異常的方式聲明, 以下方式是不合法的 比如 boolean value(String xx)、boolean value()throws Exception等是非法的
  • 可以通過(guò)default成員指定一個(gè)默認(rèn)值,比如 String level() defalut “LOW_LEVEL”, int high() default 2 是合法的,當(dāng)然也可以不指定默認(rèn)值。
  • 成員類(lèi)型是受限制的,成員只能用基本類(lèi)型byte,short,char,int,long,float,double,boolean八種基本數(shù)據(jù)類(lèi)型和 String,Enum,Class,annotations等數(shù)據(jù)類(lèi)型,以及這一些類(lèi)型的數(shù)組.例如,String value();這里的參數(shù)成員就為String;   而 List foo() 、ForumServer value()是不合法的。

如果注解只有一個(gè)成員,成員名建議為value().

在使用時(shí)可以忽略成員和賦值號(hào)(=),比如 @NeedTestAnnotation(true).

當(dāng)注解類(lèi)擁有多個(gè)成員時(shí),如果僅僅對(duì)value成員進(jìn)行賦值,則也可不使用賦值號(hào)。

如果同時(shí)對(duì)多個(gè)成員進(jìn)行賦值,這必須使用賦值號(hào),比如 @DecalreParents(value=”XXX”,defaultImpl=XXX).

注解類(lèi)可以沒(méi)有成員,沒(méi)有成員的注解稱(chēng)為標(biāo)注注解,解釋程序以標(biāo)識(shí)注解存在與否進(jìn)行相應(yīng)的處理

此外,所有的注解都隱式繼承與java.lang.annotation.Annotation,但注解不允許顯示繼承其他的接口。

使用注解

我們?cè)跇I(yè)務(wù)類(lèi)中,使用NeedTestAnnotation注解,標(biāo)注業(yè)務(wù)方法是否需要測(cè)試。

如下

package com.xgj.aop.spring.advisor.anno;
/**
 * 
 * 
 * @ClassName: ForumService
 * 
 * @Description: 演示使用自定義注解@NeedTestAnnotation
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年8月23日 下午5:15:18
 */
public class ForumService {
    @NeedTestAnnotation
    public void removeTopicId(int topicId) {
        System.out.println("remove topicId" + topicId);
    }
    @NeedTestAnnotation(true)
    public void removeForumId(int forumId) {
        System.out.println("remove forumId" + forumId);
    }
}

如果注解類(lèi)和目標(biāo)類(lèi)不在同一個(gè)包中,這需要通過(guò)improt引用注解類(lèi)。

在標(biāo)注注解時(shí),可以通過(guò)以下格式對(duì)注解成員進(jìn)行賦值

@<注解名>(<成員名1>=<成員值1>,<成員名2>=<成員值2>,.....)

如果成員是數(shù)組類(lèi)型,這可以通過(guò){}進(jìn)行賦值,比如 boolean數(shù)組的成員可以設(shè)置為{true,false,true}

訪(fǎng)問(wèn)注解

我們說(shuō)過(guò),注解不會(huì)直接影響程序的運(yùn)行,但是第三方程序或者工具可以利用代碼中的注解完成特殊的任務(wù),間接控制程序的運(yùn)行。 對(duì)于RetentionPolicy.RUNTIME保留期限的注解,可以通過(guò)反射機(jī)制訪(fǎng)問(wèn)類(lèi)中的注解。

在Java5.0中,Package、Class、Constructor、Method以及Field 等反射對(duì)象都新增了訪(fǎng)問(wèn)注解信息的方法:<T extends Annotation>T getAnnotation(Class<T> annotationClass)該方法支持通過(guò)泛型直接返回注解對(duì)象.

下面通過(guò)反射來(lái)訪(fǎng)問(wèn)注解,得到ForumService類(lèi)中通過(guò)@NeedTestAnnotation注解所承載的測(cè)試需求

package com.xgj.aop.spring.advisor.anno;
import java.lang.reflect.Method;
import org.junit.Test;
/**
 * 
 * 
 * @ClassName: AnnotaitionSelfDefineTool
 * 
 * @Description: 訪(fǎng)問(wèn)注解
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年8月23日 下午5:18:26
 */
public class AnnotaitionSelfDefineTool {
    @Test
    public void test() {
        // 得到對(duì)應(yīng)的Class
        Class<ForumService> clazz = ForumService.class;
        // 因?yàn)闃?biāo)注在方法上,所以先得到對(duì)應(yīng)的方法
        Method[] methods = clazz.getDeclaredMethods();
        System.out.println(clazz.getName() + " 有 " + methods.length + " 個(gè)方法");
        // 遍歷方法
        for (Method method : methods) {
            // 獲取方法上的注解
            NeedTestAnnotation needTestAnnotation = method
                    .getAnnotation(NeedTestAnnotation.class);
            // 判斷是否有標(biāo)注此注解
            if (needTestAnnotation != null) {
                // 獲取注解中定義的值,做處理
                if (needTestAnnotation.value()) {
                    System.out.println(method.getName() + "需要測(cè)試");
                } else {
                    System.out.println(method.getName() + "不需要測(cè)試");
                }
            }
        }
    }
}

單元測(cè)試結(jié)果:

com.xgj.aop.spring.advisor.anno.ForumService 有 2 個(gè)方法

removeTopicId不需要測(cè)試

removeForumId需要測(cè)試

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

相關(guān)文章

  • java 實(shí)現(xiàn)最小二叉樹(shù)堆排序的實(shí)例

    java 實(shí)現(xiàn)最小二叉樹(shù)堆排序的實(shí)例

    這篇文章主要介紹了java 實(shí)現(xiàn)最小二叉樹(shù)堆排序的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • java設(shè)計(jì)模式之建造者模式學(xué)習(xí)

    java設(shè)計(jì)模式之建造者模式學(xué)習(xí)

    建造者模式(Builder Pattern)主要用于“分步驟構(gòu)建一個(gè)復(fù)雜的對(duì)象”,在這其中“分步驟”是一個(gè)穩(wěn)定的算法,下面給出了詳細(xì)的示例
    2014-01-01
  • Java的函數(shù)式接口@FunctionalInterface的使用說(shuō)明

    Java的函數(shù)式接口@FunctionalInterface的使用說(shuō)明

    這篇文章主要介紹了Java的函數(shù)式接口@FunctionalInterface的使用說(shuō)明,我們常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解,需要的朋友可以參考下
    2024-01-01
  • Java單例模式的創(chuàng)建,破壞和防破壞詳解

    Java單例模式的創(chuàng)建,破壞和防破壞詳解

    大家所熟知的單例模式只能創(chuàng)建唯一一個(gè)實(shí)例,今天我們介紹幾種常見(jiàn)的單例模式,同時(shí)說(shuō)一說(shuō)如何破壞單例模式,同時(shí)又怎么來(lái)防破壞
    2021-09-09
  • 自定義BufferedReader的實(shí)例

    自定義BufferedReader的實(shí)例

    下面小編就為大家分享一篇自定義BufferedReader的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • Java中使用HashMap改進(jìn)查找性能的步驟

    Java中使用HashMap改進(jìn)查找性能的步驟

    這篇文章主要介紹了Java中使用HashMap改進(jìn)查找性能的步驟,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-02-02
  • Mybatis中TypeHandler使用小結(jié)

    Mybatis中TypeHandler使用小結(jié)

    MyBatis的TypeHandler是一個(gè)強(qiáng)大的機(jī)制,它為我們提供了一種靈活的方式來(lái)處理Java類(lèi)型與數(shù)據(jù)庫(kù)類(lèi)型之間的轉(zhuǎn)換,本文主要介紹了Mybatis中TypeHandler使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • Java幾種常用JSON庫(kù)性能比較詳解

    Java幾種常用JSON庫(kù)性能比較詳解

    這篇文章主要介紹了Java幾種常用JSON庫(kù)性能比較詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • java微信開(kāi)發(fā)第二步 獲取消息和回復(fù)消息

    java微信開(kāi)發(fā)第二步 獲取消息和回復(fù)消息

    這篇文章主要為大家分享java微信開(kāi)發(fā)的第二步,如何獲取消息和回復(fù)消息,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Java?String之contains方法的使用詳解

    Java?String之contains方法的使用詳解

    這篇文章主要介紹了Java?String之contains方法的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評(píng)論