閱讀942 返回首頁    go 京東網上商城


Java注解

一、什麼是JAVA的注解?

     注解,顧名思義就是對某種事物添加一個注釋說明的意思,標注某種事物的特征以及形態,供日後其它人遇到該事物時有一個直觀的認識。JAVA注解又叫JAVA標注,JAVA語言提供一套機製,可以在包、類(包括接口、枚舉、注解)、方法、字段(包括常量)、方法參數、局部變量、構造器和注解這些元素上添加標注(即為這些元素附上一些標識信息),在某些業務需要的情況下,可以通過JAVA的反射機製獲得這些元素的標識信息,做進一步的操作。

 

二、自定義JAVA注解

1、為什麼要自定義注解?

在JDK5.0以後默認提供了三個常用的注解類:
1)、@Override:隻能作用於方法之上,用來告訴別人這個方法是改寫父類的一個方法。
2)、@Deprecated:可以作用於程序中任何元素之上,用 @Deprecated 注釋的程序元素,不鼓勵程序員使用,通常是因為它很危險或存在更好的選擇。在使用不被讚成的程序元素或在不被讚成的代碼中執行重寫時,編譯器會發出警告。
3)、@SuppressWarnings:隻能作用於TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE上,用於關閉編譯器提示的警告信息。
因為在日常工作中,三個注解類是完全不能滿足業務需求的,所以要根據自己的業務需求,定義自己的注解類。


2、如何自定義注解?

自定義注解的步聚:
1)、通過@interface關鍵字聲明注解名稱,和定義類(class)、接口(interface)、枚舉(emum)的方式一樣,隻有關鍵詞不一樣,用“@interface”標識。
2)、使用JAVA內置的四個元注解對自定義的注解作用範圍做一些限製。

3、什麼是元注解?

元注解,就是專門用來定義注解的注解,主要作用就是用於約束自定義注解的功能。比如注解隻能用在方法上、類上或字段上。其中JDK5.0中內置的三個注解,也是通過元注解來約束的。

元注解有哪些呢?
/*
 * JDK自帶的元注解有:@Target,@Retentio,@Documente,@Inherited
 * 
 * @Target:指示該注解類型用於什麼元素之上,如果注解沒有添加@Target標示,則可以作用於任一程序元素上,如果加上了@Target注解類型約束,則編譯器會強製檢查作用於程序元素上的限製。
 * 可選的ElementType注解類型包括:
 * ElementType.ANNOTATION_TYPE:隻能作用於注解類型上
 * ElementType.CONSTRUCTOR:隻能作用於構造方法上
 * ElementType.FIELD:隻能作用於字段上(包括枚舉常量)
 * ElementType.LOCAL_VARIABLE:隻能作用於局部變量上
 * ElementType.METHOD:隻能作用於方法上
 * ElementType.PACKAGE:隻能作用於包上
 * ElementType.PARAMETER:隻能作用於方法參數聲明上
 * ElementType.TYPE:隻能作於類、接口、枚舉、注解上
 * 
 * @Retention:指示在什麼級別保留注解信息。如果注釋類型聲明中不存在Retention,則保留策略默認為 RetentionPolicy.CLASS。 
 * 可選的RetentionPolicy保留級別包括: 
 * RetentionPolicy.SOURCE:僅保留在源代碼中,javac編譯完後,會丟棄注解。不會保存在編譯好的class文件上。
 * RetentionPolicy.CLASS:保留在源代碼和class文件中,jvm加載class字節碼文件時,不會加載注解。
 * RetentionPolicy.RUNTIME:即保留在源代碼和class文件中,也會被jvm加載到內存當中,所以可通過反射的方式讀取注解信息。
 * 
 * @Documented:標示了此注解的元素,注釋將成為注解元素公共API的一部分。
 * 
 * @Inherited:指示注釋類型被自動繼承。如果在注釋類型聲明中存在 Inherited 元注釋,並且用戶在某一類聲明中查詢該注釋類型,同時該類聲明中沒有此類型的注釋,則將在該類的超類中自動查詢該注釋類型。此過程會重複進行,直到找到此類型的注釋或到達了該類層次結構的頂層 (Object) 為止。如果沒有超類具有該類型的注釋,則查詢將指示當前類沒有這樣的注釋。
 */

4、自定義注解及使用示例

1)、自定義一個類級別的注解TypeAnnotation

package annotation;

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;

@Retention(RetentionPolicy.RUNTIME)	//此注解會一直保留到運行時
@Target(ElementType.TYPE)			//此注解應用於類、接口、枚舉、注解上
@Documented	//此注解會包含在javadoc中
public @interface TypeAnnotation {

	String value();
	
}

2)、自定義一個方法級別的注解MethodAnnotation

package annotation;

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;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface MethodAnnotation {

	String name();
	
	String address();
	
}

3)、定義一個注解使用類TestAnnotation,並使用這兩個注解

package annotation;

@TypeAnnotation("hi,i am TypeAnnotation...")
public class AnnotationResource {

	@MethodAnnotation(name="zhangsan",address="北京")
	public void getPersonInfo() {
		System.out.println("hello,i am zhangsan");
	}
	
	@MethodAnnotation(name="lisi",address="上海")
	public String getPersonInfo2() {
		return "lisi,來自上海!";
	}
	
}

4)、然後使用反射的方式獲取這兩個注解的信息

package annotation;

import java.lang.reflect.Method;

/**
 * 測試注解的使用
 */
public class TestAnnotation {

	public static void main(String[] args) {
		AnnotationResource ar = new AnnotationResource();
		Class clazz = ar.getClass();
		//通過反射獲得類注解信息
		if (clazz.isAnnotationPresent(TypeAnnotation.class)) {
			TypeAnnotation typeAnnotation = (TypeAnnotation) clazz.getAnnotation(TypeAnnotation.class);
			System.out.println(typeAnnotation.value());
		}
		
		//通過反射獲得方法注解信息
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			if (method.isAnnotationPresent(MethodAnnotation.class)) {
				MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);
				System.out.print("姓名:" + methodAnnotation.name() + "\t");
				System.out.println("地址:" + methodAnnotation.address() + "\t");
			}
		}
	}
}

注意:
1、自定義的Annotation,隱式的繼續自java.lang.Annotation,所以不能在繼承其它的類或接口。
2、在Annotation中聲明的方法隻能是public的,或者默認不加訪問修飾符。
3、方法的返回值類型隻限8種基本類型byteint、short、longfloat、double、char、boolean,和String、enum、annotation、Class,以及這些類型的數組。
4、方法不能有參數
5、方法不能拋異常

最後更新:2017-04-02 22:16:20

  上一篇:go mysql error handler 例
  下一篇:go Java解析XML(二)、DOM