Java 注解Annotation
1.創建一個注解
創建注解跟接口差不多,不過要在interface前加個@,可以用default在方法后面設置默認值,方法的返回類型包括基本類型、String、Class、enum、Annotation、以上類型數組。還要通過元注解(@Retention、@Target)定義其作用域、有效范圍。舉一個例子
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface demo{
public int value();//只有當value()是唯一需要使用時賦值,才可以這樣簡寫@demo(0)
public String bbb() default "demo";
public Class<?> ccc() default Date.class;
public ElementType ddd() default ElementType.TYPE;
public Target eee() default @Target(value = { ElementType.TYPE });
public char[] fff() default {'a','b'};
}
2.元注解
元注解專職負責注解其他注解,共四種 @Target、@Retention、@Documented(將此注解包含在Javadoc中)、@Inherited(允許子類繼承父類),其實元注解跟泛型的通配符(?)差不多概念。先介紹下注解中用到的兩個枚舉參數
元注解@Target的參數
public enum ElementType
{// 分別表示的作用范圍
TYPE, // 類、接口、注解、泛型
FIELD, // 域
METHOD, // 方法
PARAMETER, // 參數
CONSTRUCTOR, // 構造方法
LOCAL_VARIABLE, // 局部變量
ANNOTATION_TYPE, // 應用于另一個注解上
PACKAGE; // 包
private ElementType() {}
} 元注解@Retention的參數
public enum RetentionPolicy
{
SOURCE, //注解將被編譯器丟棄
CLASS, //保存在class文件中,VM 丟棄
RUNTIME; //運行時保留,可通過反射獲取
private RetentionPolicy() {}
} 元注解@Target,表示該注解可以用在什么地方
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Target
{
ElementType[] value();
} 元注解@Retention,注解的保存級別
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Retention
{
RetentionPolicy value();
}
3. Java內置注解
@Override, 表示當前方法覆蓋父類中的方法,如果父類沒有該方法,編譯器錯誤
//源碼
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Override {} @Deprecated, 用這個標注方法,就會出現一條橫線,方法就基本廢了
//源碼
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.LOCAL_VARIABLE,
ElementType.METHOD,
ElementType.PACKAGE,
ElementType.PARAMETER,
ElementType.TYPE})
public @interface Deprecated {} @SuppressWarnings({"all"}) 消除警告用
//源碼
@Target({ElementType.TYPE,
ElementType.FIELD,
ElementType.METHOD,
ElementType.PARAMETER,
ElementType.CONSTRUCTOR,
ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();// 這個數組的參數在下面
}
|
下面舉一個栗子
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
public class AnnotationTest implements InvocationHandler {
private Object obj;
public AnnotationTest(Object obj) {
this.obj = obj;
}
// ----------------定義注解--------------------
// 讓此枚舉保留到運行時
@Retention(RetentionPolicy.RUNTIME)
// 用在方法上
@Target({ ElementType.METHOD })
public @interface Transaction {
public boolean value() default true;
}
// ---------------定義一個接口------------------
public interface IDao {
@Transaction
// 使用注解
public void remove();
}
// --------------實現接口---------------------
public static class DaoImpl implements IDao {
Queue<String> queue;
public DaoImpl(Queue<String> queue) {
this.queue = queue;
}
@Override
public void remove() {
// 刪除報錯,要求回滾
if (queue.peek().equals("stop")) {
throw new NullPointerException();
}
System.err.println(queue.poll());
}
}
// --------------得到代理類---------------------
public Object getProxy() {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object paramObject, Method paramMethod,
Object[] paramArrayOfObject) throws Exception {
// 取方法上面的注解Transaction
Transaction tran = paramMethod.getAnnotation(Transaction.class);
boolean isTran = false;
if (tran != null) {
isTran = tran.value();// 判斷是否需要事務
}
Object rtnObj = null;
try {
if(isTran){System.err.println("啟動事務");}
rtnObj = paramMethod.invoke(obj, paramArrayOfObject);
if(isTran){System.err.println("提交事務");}
}catch(Exception e){
if(isTran){System.err.println("回滾事務");}
throw e;
}
return rtnObj;
}
public static void main(String[] args) {
Queue<String> queue = new LinkedList<String>();
Collections.addAll(queue, "1", "stop", "2");
AnnotationTest test = new AnnotationTest(new DaoImpl(queue));
IDao dao = (IDao) test.getProxy();
try {
while (queue.peek() != null) {
dao.remove();
}
} catch (Exception e) {
System.out.println("-----------------");
for (String str : queue) {
System.out.println(str);
}
}
}
} 輸出:
啟動事務
1
提交事務
啟動事務
回滾事務
-----------------
stop
2
轉自:http://flyouwith.iteye.com/blog/2174420
本文由用戶 cwf8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!