Java自定義註解 – JAVA編程語言程序開發技術文章

Java註解目前廣泛被應用。spring中的基於註解的依賴註入、Spring Web MVC中的Route、PlayFramework中的基於註解的Validation等。

使用註解,可以在適當地方替代XML的繁瑣。

 

現在來看看,如何自定義註解。

目標:通過註解方式,定義屬性的默認值。例如:

[java] public class DefaultUse { 
     
    @Default(value = "Hello Annotation") 
    private String msg; 
     
    public void say(){ 
        System.out.println(msg); 
    } 

public class DefaultUse {
 
 @Default(value = "Hello Annotation")
 private String msg;
 
 public void say(){
  System.out.println(msg);
 }
}

 

一、新建Annotation

[java] import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
 
/**
 * @Retention 指定註釋的生存時期
 * CLASS:註釋記錄在類文件中,但在運行時 VM 不需要保留註釋。
 * RUNTIME:註釋記錄在類文件中,在運行時 VM 將保留註釋,因此可以使用反射機制讀取註釋內容。
 * SOURCE:編譯器要丟棄的註釋。
 */ 
@Retention(RetentionPolicy.RUNTIME)  
 
/**
 * @Target 
 * 指示註釋類型所適用的程序元素的種類,如果註釋類型聲明中不存在 Target 元註釋,
 * 則聲明的類型可以用在任一程序元素上。
 * ElementType.ANNOTATION_TYPE:註釋類型聲明
 * ElementType.CONSTRUCTOR:構造方法聲明
 * ElementType.FILED:字段聲明
 * ElementType.LOCAL_VARIABLE:局部變量聲明
 * ElementType.METHOD:方法聲明
 * ElementType.PACKAGE:包聲明
 * ElementType.PARAMETER:參數聲明
 * ElementType.TYPE:類、借口或枚舉聲明
 */ 
@Target(ElementType.FIELD) 
public @interface Default { 
    String value(); //默認值  

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

/**
 * @Retention 指定註釋的生存時期
 * CLASS:註釋記錄在類文件中,但在運行時 VM 不需要保留註釋。
 * RUNTIME:註釋記錄在類文件中,在運行時 VM 將保留註釋,因此可以使用反射機制讀取註釋內容。
 * SOURCE:編譯器要丟棄的註釋。
 */
@Retention(RetentionPolicy.RUNTIME) 

/**
 * @Target
 * 指示註釋類型所適用的程序元素的種類,如果註釋類型聲明中不存在 Target 元註釋,
 * 則聲明的類型可以用在任一程序元素上。
 * ElementType.ANNOTATION_TYPE:註釋類型聲明
 * ElementType.CONSTRUCTOR:構造方法聲明
 * ElementType.FILED:字段聲明
 * ElementType.LOCAL_VARIABLE:局部變量聲明
 * ElementType.METHOD:方法聲明
 * ElementType.PACKAGE:包聲明 www.aiwalls.com
 * ElementType.PARAMETER:參數聲明
 * ElementType.TYPE:類、借口或枚舉聲明
 */
@Target(ElementType.FIELD)
public @interface Default {
 String value(); //默認值
}

二、實際類中使用

[java] public class DefaultUse { 
     
    @Default(value = "Hello Annotation") 
    private String msg; 
     
    public void setMsg(String msg) { 
        this.msg = msg; 
    } 
 
    public void say(){ 
        System.out.println(msg); 
    } 

public class DefaultUse {
 
 @Default(value = "Hello Annotation")
 private String msg;
 
 public void setMsg(String msg) {
  this.msg = msg;
 }

 public void say(){
  System.out.println(msg);
 }
}
三、註解解析過程

[java] import java.beans.PropertyDescriptor; 
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
 
public class DefaultTest { 
    public static void main(String args[]) throws Exception{ 
        DefaultUse use = new DefaultUse(); 
         
        //Default註解的處理過程  
        //這裡使用反射機制完成默認值的設置  
        Field[] fileds = use.getClass().getDeclaredFields(); 
         
        for(Field filed : fileds){ 
            Default annotation = filed.getAnnotation(Default.class); 
            if(annotation != null){ 
                PropertyDescriptor pd = new PropertyDescriptor(filed.getName(), DefaultUse.class); 
                Method setterName = pd.getWriteMethod(); 
                 
                if(setterName!=null){ 
                    String value = annotation.value(); 
                    filed.setAccessible(true); 
                    setterName.invoke(use, value); 
                } 
            } 
        } 
         
        use.say(); 
    } 

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class DefaultTest {
 public static void main(String args[]) throws Exception{
  DefaultUse use = new DefaultUse();
  
  //Default註解的處理過程
  //這裡使用反射機制完成默認值的設置
  Field[] fileds = use.getClass().getDeclaredFields();
  
  for(Field filed : fileds){
   Default annotation = filed.getAnnotation(Default.class);
   if(annotation != null){
    PropertyDescriptor pd = new PropertyDescriptor(filed.getName(), DefaultUse.class);
    Method setterName = pd.getWriteMethod();
    
    if(setterName!=null){
     String value = annotation.value();
     filed.setAccessible(true);
     setterName.invoke(use, value);
    }
   }
  }
  
  use.say();
 }
}

 

摘自  God's blog
 

發佈留言