註解基礎篇:自定義Java Annotation
## 寫在前面
JDK5增加了對Annotation(註解)的支援,Annotation是程式碼裡的特殊標記,這些標記可以在編譯,類載入和執行時被讀取讀取出來,並執行相應的處理和操作!比如在不改變程式邏輯的情況下,開發人員可以在程式碼中嵌入一些補充資訊,程式碼分析和開發部署工具APT(AnnotationProcessTool)可以通過這些資訊進行驗證或部署。
APT工具在處理註解時,會根據原始檔的Annotation資訊,生成附加原始檔或者進行一些其他操作!最後在車鞥徐編譯時期,APT會將生成的附加原始檔和原有原始檔進行合併,生成最終的*.class檔案!預設情況下,Annotation可以修飾任何程式元素(ElementType),包括類,介面,成員方法,成員變數。根據Annotation是否帶成員變數,可分為兩類:
- 標記Annotation,根據自身存在與否提供資訊;
- 元資料Annotation,根據接收的成員變數值,提供元資料資訊;
## 設計Annotation
與定義一個介面很相似,自定義Annotation使用@interface關鍵字:
//字元定義Annotation
public @interface CustomAnno {
}
//使用上面自定義的Annotaiton,修飾類
@CustomAnno
public class BeautifulClass {
//修飾成員方法
@CustomAnno
public void toPlus() {...}
}
Annotation也可以有成員變數,如下定義:
public @interface HelloAnno {
//定義帶兩個成員變數的Annotation
//Annotaion中的成員變數以方法的形式來定義
String apple();
Integer pear();
}
//使用帶成員變數的Annotation
public class beautifulClass2 {
//需要為成員變數賦值
@HelloAnno(apple="apple", pear=101)
public void toPlus() {...}
}
當然,帶成員變數的Annotation也可以為期指定初始值(預設值),在哪在使用註解的時候就不需要再次未改成員變數賦值了;當然,如果需要的話也可以再次賦值,則新值會覆蓋預設值!如下:
public @interface BlackAnno {
//定義帶兩個成員變數的Annotation
//Annotaion中的成員變數以方法的形式來定義
//指定成員變數的預設值,使用default關鍵字
String apple() default "black";
Integer pear() default 101;
}
//使用帶成員變數的Annotation
public class beautifulClass3 {
//@HelloAnno已經指定了預設值
//則使用時不需要賦值,直接使用即可
@HelloAnno
public void toPlus1() {...}
//如果需要,也可以為成員變數賦值,則會覆蓋預設值
@HelloAnno(apple="apple", pear=101)
public void toPlus2() {...}
}
## 提取Annotation
使用Annotation修飾了類以及成員方法後,這些Annotation不會自己生效,必須有開發者提供相應的工具來提取並處理Annotation資訊。
java.lang.reflect包下包含一些實現反射功能的工具類:比如定義Annotation時使用@Rentation(RetentionPolicy.RUNTIME)修飾,則Annotation會被編譯器儲存在*.class檔案中,Java在執行時會通過反射讀取類檔案中的Annotation!
AnnotatedElement介面是所有程式元素(Class,Method,Constructor等)的父介面,所以獲得某個AnnotationElement物件後,就可以呼叫該物件的如下方法來訪問Annotation註解資訊:
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
Annotation[] getAnnotations()
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)
Annotation[] getDeclaredAnnotations()
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
## 自定義註解demo
自定義一個Java註解 @CustomAnno,程式碼如下:
/**
* 自定義一個 Java 註解
* 1. @Retention(RetentionPolicy.RUNTIME)
* 執行時讀取並處理註解資訊
* 2. @Target(ElementType.METHOD)
* 自定義註解只能修飾方法
*
* Created by wondertwo on 2016/10/16.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomAnno {}
用以上自定義的註解,來修飾Person類的八個方法,程式碼如下:
/**
* Created by wondertwo on 2016/10/16.
*/
public class Person {
/**
* 使用自定義註解 @CustomAnno 修飾以下 8個方法
*/
@CustomAnno
public static void method_1() {}
@CustomAnno
public static void method_2() {}
@CustomAnno
public static void method_3() {}
@CustomAnno
public static void method_4() {}
@CustomAnno
public static void method_5() {}
@CustomAnno
public static void method_6() {}
@CustomAnno
public static void method_7() {}
@CustomAnno
public static void method_8() {}
}
測試註解,通過反射呼叫方法,程式碼如下:
/**
* Created by wondertwo on 2016/10/16.
*/
public class AnnoTest {
public static void main(String[] args) throws ClassNotFoundException {
process("me.wondertwo.annotation.Person"); //Person
}
private static void process(String clazz) throws ClassNotFoundException {
int passed= 0 , failed = 0;
//遍歷clazz對應類的所有方法
for (Method method : Class.forName(clazz).getMethods()) {
//如果該方法使用了自定義註解 @CustomAnno 修飾
if (method.isAnnotationPresent(CustomAnno.class)) {
try {
method.invoke(null);
passed++;
} catch (Exception e) {
e.printStackTrace();
System.out.println("方法 " + method + " 測試失敗,出現異常");
failed++;
}
}
}
System.out.println("一共運行了 " + (passed+failed) + " 個方法");
System.out.println("成功執行方法 " + passed + " 個");
System.out.println("失敗執行方法 " + failed + " 個");
}
}
/**
* 執行結果輸出如下:
* 一共運行了 8 個方法
* 成功執行方法 8 個
* 失敗執行方法 0 個
* Process finished with exit code 0
*/
我們的自定義註解,成功的被提取出來並執行了!
相關推薦
註解基礎篇:自定義Java Annotation
## 寫在前面 JDK5增加了對Annotation(註解)的支援,Annotation是程式碼裡的特殊標記,這些標記可以在編譯,類載入和執行時被讀取讀取出來,並執行相應的處理和操作!比如在不改變程式邏輯的情況下,開發人員可以在程式碼中嵌入一些補充資訊,程式碼分析和開發部署工具APT(AnnotationP
註解提高篇:自定義註解處理器(APT)
## 0x01 繼承AbstractProcessor抽象類 當定義好Annotation註解後,接下來就需要一個註解處理器來處理我們的自定義註解了。實現Java Annotation一般需要繼承AbstractProcessor抽象類,並且重寫其四個方法來實現提取,解析並處理自定義註解的邏輯如下: cla
自定義 Java Annotation ,讀取註解值
sta tools stp exc num value mage test lang 1. 首先是自定義註解: Java代碼 package cn.veji.hibernate.po; import java.lang.annot
分享:自定義JAVA註解
http ack 信息 element 常量 變量 分享 oca runt 元註解 元註解指用來定義註解的註解,例如:@Retention @Target Inherited @Documented等等。最為重要和經常使用的是@Retention @Target。
基礎篇:深入解析JAVA註解機制
[TOC](目錄標題) # java實現註解的底層原理和概念 - java註解是JDK1.5引入的一種註釋機制,java語言的類、方法、變數、引數和包都可以被註解標註。和Javadoc不同,java註解可以通過反射獲取標註內容 - 在編譯器生成.class檔案時,註解可以被嵌入位元組碼中,而jvm也可以保
ArcGIS Engine 開發學習-------基礎(一):自定義命令
要求:在ToolbarControl中新增一個自定義命令,點選可清除當前活動工具。 步驟: 1、建立GIS類,選擇Base Command模版,Extending ArcObjects,ArcMap MapControl or PageLayo
精通Spring Boot——第十八篇:自定義認證流程
前兩篇簡單介紹了一下使用Spring Security 使用Http Basic登入,以及Spring Security如何自定義登入邏輯。這篇文章主要介紹如何使用handler來定義認證相關的流程。 先做一些自定義的操作,如配置自定義登入頁,配置登入請求URL等。 當我們使用Spring Security時
MySQL 第八篇:自定義函式、儲存過程、遊標
本篇內容由猿道教育的課程內容整理而來。 我把MySQL的內容整理成9篇部落格,學完這9篇部落格雖不能說能成為大神,但是應付一般中小企業的開發已經足夠了,有疑問或建議的歡迎留言討論。 自定義函式 一、函式的概念與定義 1、理解函式 函式可以看作是
【tensorflow】基礎一:自定義layer並新增到計算圖中
目的 將使用者自定義的layer結合tensorflow自帶的layer組成多層layer的計算圖。 實現功能 對2D影象進行滑動視窗平均,並通過自定義的操作layer返回結果。 import
Android特效第三篇:自定義Gallery實戰(仿網易) .
Android系統提供了一個Gallery畫廊控制元件,在專案很多時候都會用到Gallery,比如新浪首頁的廣告,網易看客戶端首頁等隨處可見,今天我自己定義了一個仿網易的Gallery與大家共享。 首先請看效果圖:
Web開發之-JSP學習總結-第四篇:自定義標籤總結
一、自定義標籤開發步驟—以高仿<c:if test=""></c:if>標籤為例 1、編寫一個普通的java類,繼承SimpleTagSupport類,叫標籤處理器類。並且覆蓋doTag方法 /** * 標籤處理器類 * 1)繼承
SpringBoot第十六篇:自定義starter
作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/11058502.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 前言 這一段時間專案趕進度,故該系列部落格更新沒有之前那麼頻繁,望諒解。 SpringBoot 用起來方便,它預設集成了
Spring Boot 基礎系列教程 | 第三十二篇:使用@Async實現非同步呼叫:自定義執行緒池
推薦 Spring Boot/Cloud 視訊: 在之前的Spring Boot基礎教程系列中,已經通過《Spring Boot中使用@Async實現非同步呼叫》一文介紹過如何使用@Async註解來實現非同步呼叫了。但是,對於這些非同步執行的控制是我們保障自身
Unity Editor 基礎篇(二):自定義 Inspector 面板
自定義Inspector屬性面板 EditorGUILayout 編輯器介面佈局 這是一個編輯器類,如果想使用它你需要把它放到工程目錄下的Assets/Editor資料夾下。編輯器類在UnityEditor名稱空間下。所以當使用C#指令碼時,你需要在指令碼前面加上
Unity Editor 基礎篇(三):自定義視窗案例二
本文為本人學習上鍊接的筆記微有改動,請點選以上鍊接檢視原文,尊重樓主智慧財產權。 ----------------------------------------------------------------------------------------------
自定義Java註解(annotation)
https://www.imooc.com/learn/456 筆記 Java從1.5開始引進註解。 首先解決一個問題,為什麼要學習Java註解? 1.看懂別人寫的程式碼,尤其是框架的程式碼 2.可以是自己寫的程式碼簡潔清晰 現在開始學習Java註解了。
Java註解:自定義註解示例,利用反射進行解析
Java註解能夠提供程式碼的相關資訊,同時對於所註解的程式碼結構又沒有直接影響。在這篇教程中,我們將學習Java註解,如何編寫自定義註解,註解的使用,以及如何使用反射解析註解。 註解是Java 1.5引入的,目前已被廣泛應用於各種Java框
Android零基礎入門第24節:自定義View簡單使用
子類 protect jin 討論 我們 @+ amp 進階 運行程序 當我們開發中遇到Android原生的組件無法滿足需求時,這時候就應該自定義View來滿足這些特殊的組件需求。 一、概述 很多初入Android開發的程序員,對於Android自定義View可能比較
Android零基礎入門第40節:自定義ArrayAdapter
出發點 ppc vsa abs 顯示 osi adc this launcher ListView用起來還是比較簡單的,也是Android應用程序中最重要的一個組件,但其他ListView可以隨你所願,能夠完成很多想要的精美列表,而這正是我們接下來要學習的內容。
visual studio code教程:基礎使用和自定義設置
麻煩 安裝 顏色 必須 寫入 全局環境變量 註意 一個 preview 一、界面介紹 1.1 界面介紹 1.2 文件夾和文件的打開 文件——>打開文件夾/打開文件 1.3 新建文件/文件夾 新建文件: a. 文件——>新建文件; b. 按Ctrl+n; c