1. 程式人生 > >Java自定義註解(原理和API)初探

Java自定義註解(原理和API)初探

    今天稍稍學習了下註解,關於註解,我想大家都不陌生,目前可能在hibernate配置中可能會用的多一點,在JPA中也會用到。我想說的是學習註解可以幫助我們更好的理解註解在框架中(比如hibernate和Spirng等)的應用。

    Annotation是JDK5版本以來的新特性。目前在JavaSE中的學習中可能會經常遇到集合未指定泛型、使用java.util.Date類中的過時方法,編譯器給出warning時,均可以採用增加註解如(SuppressWarnings("unchecked")),Deprecated等來消除警告,這樣看起來會好看些。

    學習Annotation涉及到的java類包含:java.lang.annotation.Annotation。所有定義的annotation均預設實現了Annotation介面,但是要注意的是,實現Annotation介面的類並不是annotation。

    java中的annotation中包含的註解型別有Documented,Inherited,Retention,Target,其中常用的有Inherited(子類可以繼承父類的註解),Retention(註解型別要保留多久,可否利用反射機制呼叫等),Target(註解的作用物件,類,介面,方法,屬性等)。定義註解的關鍵字為@interface,關於JDK1.6自帶的註解比如SuppressWarnings("unchecked")),Deprecated等我就不介紹了,相信有一定基礎的都遇到過。

    相信在諸如hibernate和spring等框架中,我相信這些框架是使用反射讀取的註解及註解中的引數,根據這些註解和引數通過一定的邏輯來對業務進行控制的。

    下面開始自定義一個註解並講解使用,具體步驟為:

    定義註解->寫測試類->進行測試

一、定義註解:

註解一:AnnotationTest

@Retention(RetentionPolicy.RUNTIME) // 將Retention的值設定為RetentionPolicy.RUNTIME,這樣就可以在程式執行期間可以用反射對註解進行解析,設定為CLASS何SOURCE均不能
public @interface AnnotationTest {
 String value() default "good";
 String value1() default "hello";
 EnumTest value2(); //列舉型別
}
/**
 * 自定義列舉類
 *
 * @author XiaoYun 2013-07-20
 */
enum EnumTest {
 HELLO, world, welcome
}

註解二:

MyAnnotation.java
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 自定義註解
 *
 * @author XiaoYun 2013-07-20
 */
@Retention(RetentionPolicy.CLASS)//將Retention的值設定為RetentionPolicy.CLASS,程式執行的時候就不能通過反射解析
public @interface MyAnnotation {
 String value() default "hello";
 String hello();
 String world();
}

測試類(這裡為了少寫一個類,就把測試方法和類放到了一個類中):MyTest.java

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

@AnnotationTest(value1="hello", value2=EnumTest.world)
@MyAnnotation(world="world", hello="hello")
public class MyTest {
 
 @MyAnnotation(world="world", hello="hello")
 private String field;
 
 @AnnotationTest(value1="hello", value2=EnumTest.world)
 @MyAnnotation(value="xiaoyun", hello="hello", world="world")
 private void method() {  
  System.out.println("field的值為:" + field + "\nmethod from MyTest!");
 }
 
 @Override
 public String toString() {
  return "MyTest [field=" + field + "]";
 }

 /**
  * 測試方法
  * @param args
  */
 public static void main(String[] args) throws Exception {
  // 例項化物件
  MyTest test = new MyTest();
  // 獲取Class型別
  Class cls = MyTest.class;
  // 根據方法名獲取方法
  Method method = cls.getDeclaredMethod("method", null);
  // 獲取屬性
  Field field = cls.getDeclaredField("field");
  // 判斷如果該方法中包含有MyAnnotation型別的註解,則進行如下操作
  if (method.isAnnotationPresent(AnnotationTest.class)) {
   // 取消Java訪問性檢查
   field.setAccessible(true);
   method.setAccessible(true);
   // 給test物件上的field屬性賦值,並執行method方法
   field.set(test, "我是肖雲,大家好!");
   method.invoke(test, null);
   
   // 根據註解型別獲取特定的註解並列印到控制檯
   Annotation annotation = method.getAnnotation(AnnotationTest.class);
   System.out.println(annotation.annotationType() + "\n" + annotation.annotationType().getName());
  }
  
  // 獲取所有的註解並逐次迭代(這需要註解中Retention中的value為RetentionPolicy.Runntime)
  Annotation[] annotations = method.getAnnotations();
  if (annotations.length > 0) {
   System.out.println("------------列印所有註解--------------");
   for (Annotation annotation : annotations) {
    System.out.println(annotation.annotationType().getCanonicalName());
   }
  }
 }
}
    上面一個例子主要說明的是java.lang.annotation.Annotation介面中的Retention屬性(JVM是否保留註釋,是否可用反射讀取)TargetAnnotationDemo ,接下來第二個例子用到了剩下的三個屬性(Documented(不是重點,生成API文件時用),Target,Inherited),下面開始介紹:

首先還是定義註解:

TargetAnnotationDemo.java

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Target註解
 *
 * @author XiaoYun 2013-07-20
 */
@Target({ElementType.TYPE, ElementType.METHOD})  //程式型別的元素有類、介面、列舉型別;方法
@Retention(RetentionPolicy.RUNTIME) //執行時可用反射呼叫
@Inherited //子類可以繼承父類的註解
@Documented //生成doc文件時顯示該註解
public @interface TargetAnnotationDemo {
 String value() default "hello";
 String value1();
}

第二步,寫測試用例:

@TargetAnnotationDemo(value1 = "good")
public class TargetTest {
 @TargetAnnotationDemo(value1 = "good")
 public int add(int a, int b) {
  return a + b;
 }
}

/**

*子類,繼承自TargetTest ,同時繼承父類的TargetAnnotationDemo

*@author xiaoyun 2013-07-21

*/
class TargetTestChild extends TargetTest {
 @Override
 public int add(int a, int b) {
  // TODO Auto-generated method stub
  return super.add(a, b);
 }
}

第三步:

寫測試類,TestTarget.java

import java.lang.annotation.Annotation;

public class TestTarget {
 public static void main(String[] args) {
  //例項化父類
  TargetTest parent = new TargetTest();
  //例項化子類
  TargetTestChild child = new TargetTestChild();
  //獲取父類的型別
  Class cls = TargetTest.class;
  //獲取子類的型別
  Class childCls = TargetTestChild.class;
  //獲取父類的註解
  Annotation[] pAnnotations = cls.getAnnotations();
  if (pAnnotations.length > 0) {
   System.out.println("父類的註解:");
   for (Annotation annotation : pAnnotations) {
    System.out.println(annotation.annotationType().getName());   
   }
  }
  //獲取子類的註解
  Annotation[] cAnnotations = childCls.getAnnotations();
  if (cAnnotations.length > 0) {
   System.out.println("子類的註解:");
   for (Annotation annotation : cAnnotations) {
    System.out.println(annotation.annotationType().getName());
   }
  }
 }
}

  該例子主要用到了java.lang.annotation.Annotation中的所有註解型別。對於Retention,Target,Inherited和Documented這是個註解型別,需要重點掌握前三個,第四個很少用到。

   這上面的兩個例子都能正常執行,我的環境依然是,JDK1.6。對於生成doc文件的問題,你也可以通過javadoc命令來生成,但是如果你的開發工具時myeclipse8.6的話,可以通過project->Generate Javadoc來生成doc文件,通過去掉和加上@Documented註解型別來觀察在文件中是否有對應的說明(當然去掉或加上後需要重新生成下)。

   這次先寫到這裡,關於註解在程式和框架中的應用案例,後面等我學習後會進行更新和發表,謝謝各位同行關注。

    歡迎各位同行和前輩們提出問題,對程式或者我組織的語言進行批評指導。

相關推薦

Java定義註解(原理API)初探

    今天稍稍學習了下註解,關於註解,我想大家都不陌生,目前可能在hibernate配置中可能會用的多一點,在JPA中也會用到。我想說的是學習註解可以幫助我們更好的理解註解在框架中(比如hibernate和Spirng等)的應用。     Annotation是JDK5版本以來的新特性。目前在JavaSE

Java定義註解的使用場景原理

什麼是註解?       對於很多初次接觸的開發者來說應該都有這個疑問?Annontation是Java5開始引入的新特徵,中文名稱叫註解。它提供了一種安全的類似註釋的機制,用來將任何的資訊或元資料(metadata)與程式元素(類、方法、成員變數等)進行關聯。為程式的元素(類、方法、成員變數)加上更直觀更明

JAVA定義註解的使用定義

 最近有所瞭解到自定義註解的應用,因此學習了一下,在專案後臺介面開發中,資料的傳輸經常有對資料內容格式及一些資訊規則的校驗,應用註解在資料進入後臺的開始使用自定義註解是一種比較可靠的方案。 一、註解的概念及分類        1.首先我們來看一下什麼是註解:        

java定義註解以及原理

import java.util.Arrays; import java.util.List; import com.puhui.flowplatform.manage.filter.RightFilter; import org.springframework.aop.BeforeAdvice; impo

Java定義註解執行時靠反射獲取註解

<span style="font-family:SimHei;font-size:18px;color:#663300;"><strong><span class="bh_code_a_Java_keywords">public</span> <span

JAVA定義註解提取註解資訊

第一節:定義註解       定義新的Annotation型別使用@interface關鍵字(在原有interface關鍵字前增加@符號)。定義一個新的Annotation型別與定義一個介面很像,例如: public @interface Test{ } 定義完該Annot

Java定義註解 springMVC攔截器 配合使用記錄系統操作日誌的案例

自定義註解的用法, 好多人不知道, 在這裡, 程式碼的註釋中, 我已經詳細的介紹了, 另外就是很多人不知道自定義註解如何使用, 這裡配合springMVC攔截器, 做一個非常實用的案例. 案例: 記錄系統操作的日誌 首先是定義註解: package cn.wxy.ssm

Java定義註解反射校驗數據

sda new out 格式 是否 本地 imp 使用範圍 數據類型 package com.annotations.ecargo; import java.lang.annotation.ElementType; import java.lang.annotati

java定義註解

不包含 doc 1.2 color 子類 局部變量 ati 包含 ant Java註解是附加在代碼中的一些元信息,用於一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。註解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annot

java 定義註解

tar 基本用法 而且 最簡 ida outline plain 現在 傳播 參考鏈接:https://blog.csdn.net/hbzyaxiu520/article/details/6212969 JAVA自定義註釋(Target,Retention,Document

Java 定義註解&通過反射獲取類、方法、屬性上的註解

反射 JAVA中的反射是執行中的程式檢查自己和軟體執行環境的能力,它可以根據它發現的進行改變。通俗的講就是反射可以在執行時根據指定的類名獲得類的資訊。   註解的定義 註解通過 @interface 關鍵字進行定義。 /** * 自定義註解 *

Java定義註解之元註解(meta-annotation)Target、Retention、Documented、Inherited介紹

元註解:   元註解的作用就是負責註解其他(如:自定義)註解,用來對其它 annotation型別作說明。Java定義了4個標準的meta-annotation型別:    [email protected]    [email protected

java定義註解2】java定義註解結合Spring AOP

      承接上一篇,註解應用於屬性,本篇定義了一個用於方法的註解,結合Spring AOP 實現 切面程式設計。       以下demo演示使用了SpringBoot,與SSM中使用方式大致相同,效果如下: 1、自定義註解(用

java定義註解1】java定義註解-屬性

        關於自定義註解,以前專案種應用的不多,最近看新專案過程中發現了挺多自定義註解相關內容,使用起來比較巧妙,於是 總結了兩種方式,記錄如下:         第一種:結合反射進行屬性注入,程式碼如下:

java 定義註解驗證 (僅限於實體屬性值上的註解

資源下載地址:http://download.csdn.net/detail/weilai_zhilu/9761533   該驗證主要包含三部分 註解驗證類 註解處理方法類 實體類 測試類 第一部分:註解驗證類(此部分暫時只寫了三個驗證類) 下面

java定義註解解析及相關場景實現

註解(Annotation)是java1.5之後提供的一種語法。其主要作用是編譯檢查(比如@override)和程式碼分析(通過程式碼中添加註解,利用註解解析器對添加了註解的程式碼進行分析,獲取想要的結果,一般自定義的註解都是這一種功能)。 1.1 JDK提供的註解 JDK提供的

java定義註解在service層不生效原因

在做對資料加redis快取時,我這面採用了Spring-Aop的方式通過切面將資料存放在redis中,但是業務場景是,當前端呼叫了controller層的介面時,會走一些簽名校驗,如果校驗過了才會真正呼叫service層去取資料,所以我自己定義的註解載入controlle

java定義註解學習(一)_demo小練習

自定義註解 現在大家開發過程中,經常會用到註解。 比如@Controller 等等,但是有時候也會碰到自定義註解,在開發中公司的記錄日誌就用到了自定義註解。身為渣渣猿還是有必要學習下自定義註解的。 這篇我們先寫一個簡單的註解列子,不會立馬介紹各種什麼元註解。從例子中感受下註解的作用 定義個註解 packa

java定義註解學習(二)_註解詳解

上篇文章,我們簡單的實現了一個自定義註解,相信大家對自定義註解有了個簡單的認識,這篇,這樣介紹下註解中的元註解和內值註解 整體圖示 內建註解 @Override 重寫覆蓋 這個註解大家應該經常用到,主要在子類重寫父類的方法,比如toString()方法 package com.kevin.demo;

java定義註解學習(三)_註解解析及應用

上篇文章已經介紹了註解的基本構成資訊。這篇文章,主要介紹註解的解析。畢竟你只聲明瞭註解,是沒有用的。需要進行解析。主要就是利用反射機制在執行時進行檢視和利用這些資訊 常用方法彙總 在Class、Field、Method、Constructor中都有如下方法: //獲取所有的註解 public Annota