Java註解

總結

1.註解只是相當於一種標識,標誌着被修飾的類,方法,屬性等應該具有的公共的功能。這一點可以從註解的源碼看 出來,註解的源碼只有屬性變量,並沒有方法;這些屬性變量的不同取值映射爲不同的功能
2.通過反射解析出註解的屬性值,並根據屬性值是否爲指定的值,來判斷是否執行相關代碼

1:Java中常見註解

詳細介紹:基本內置註解

  1. @Override
    用在方法上,表示這個方法重寫了父類的方法,如toString()。
  2. @Deprecated
    表示這個方法已經過期,不建議開發者使用。(暗示在將來某個不確定的版本,就有可能會取消掉)
  3. @SafeVarargs
    參數安全類型註解。它的目的是提醒開發者不要用參數做一些不安全的操作,它的存在會阻止編譯器產生 unchecked 這樣的警告
  4. @FunctionalInterface
    用於約定函數式接口。 如果接口中只有一個抽象方法(可以包含多個默認方法或多個static方法),該接口稱爲函數式接口。函數式接口其存在的意義,主要是配合Lambda 表達式 來使用。

2: 註解分類

按運行機制分:

  1. 源碼註解
    註解只在源碼中存在,編譯成.class文件就不存在了
  2. **編譯時註解 **
    註解在源碼和.class文件中都會存在。比如說@Override
  3. **運行時註解 **
    在運行階段還會起作用,甚至會影響運行邏輯的註解。比如說@Autowired

3:自定義註解

  1. **自定義註解的語法要求 **
package grammar;

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



/**
* @Description  自定義註解的語法要求
* @since  2018年10月29日 下午4:47:07
* @author 
*/

/*****************   元註解    **********************************/
/*@Target 表示這個註解能放在什麼位置上,是隻能放在類上?還是即可以放在方法上,又可以放在屬性上
 * 
 *  ElementType.TYPE:能修飾類、接口或枚舉類型
	ElementType.FIELD:能修飾成員變量
	ElementType.METHOD:能修飾方法
	ElementType.PARAMETER:能修飾參數
	ElementType.CONSTRUCTOR:能修飾構造器
	ElementType.LOCAL_VARIABLE:能修飾局部變量
	ElementType.ANNOTATION_TYPE:能修飾註解
	ElementType.PACKAGE:能修飾包 
 * */
@Target({ElementType.METHOD ,  ElementType.TYPE})

/*@Retention 
 * 表示生命週期,
 * 
 * RetentionPolicy.SOURCE: 註解只在源代碼中存在,編譯成class之後,就沒了。@Override 就是這種註解
 * 
 * RetentionPolicy.CLASS: 註解在java文件編程成.class文件後,依然存在,但是運行起來後就沒了
 * 						  @Retention的默認值,即當沒有顯式指定@Retention的時候,就會是這種類型。
 * 
 * RetentionPolicy.RUNTIME: 註解在運行起來之後依然存在,程序可以通過反射獲取這些信息
 * 
 * */
@Retention( RetentionPolicy.RUNTIME)

/*@Inherited 表示該註解具有繼承性
如果一個超類被 @Inherited 註解過的註解進行註解的話,那麼如果它的子類沒有被任何註解應用的話,那麼這個子類就繼承了超類的註解。*/
@Inherited

//元註解肯定是和文檔有關。它的作用是能夠將註解中的元素包含到 Javadoc 中去
@Documented

//使用 @interface 關鍵字定義註解
public @interface Description {
	
	/* 成員變量
	 * 1. 註解的定義中以“無形參的方法”形式來聲明,其方法名定義了該成員變量的名字,其返回值定義了該成員變量的類型
	 * 
	 * 2. 註解中定義屬性時它的類型必須是 8 種基本數據類型外加 類、接口、註解及它們的數組
	 * 
	 * 3. 如果註解只有一個成員,則成員名必須取名爲 value() ,在使用時可以忽略成員名和賦值號(=)
	 * 
	 * 4. 註解類可以沒有成員,沒有成員的註解稱爲標識註解
	 * */
	
	String desc();
	
	String author();
	
	//可以用 default 爲成員指定一個默認的值
	int age() default 18;
}
  1. **使用自定義註解 **
@<註解名>(<成員名1>=<成員值1>,<成員名2>=<成員值2>,..)
package grammar;
@Description(desc="I am" ,author="liu",age=22)
public class UseAnnotation {
	public String Test() {
		return "red";
	}
}
  1. **解析註解 **
    概念: 通過反射獲取類、函數或成員上的運行時註解信息,從而實現動態控制程序運行的邏輯。注意,解析註解時, @Retention(RetentionPolicy.RUNTIME) 是必須的。
    1. 先獲取類對象
    2. 類對象調用 isAnnotationPresent(Class<? extends Annotation> annotationClass)判斷是否應用了某個註解
    3. 通過 getAnnotation() 方法來獲取 Annotation 對象,或者getAnnotations() 方法獲取所有應用在該類上的註解

示例:
註解類:

package grammar;
@Target({ElementType.METHOD ,  ElementType.TYPE})
@Retention( RetentionPolicy.RUNTIME)
@Inherited
@Documented

public @interface DesSimple {
	String value();
}

應用註解類:

package grammar;
@DesSimple("this is a type ano")
public class Child {
	
	@DesSimple("this is a method ano")
	public String name() {
		return "name";
	}
}

解析註解類:

package grammar;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class ParseAnnotation {
	public static void main(String[] args) {
		try {
			//1.使用類加載器加載類對象
			Class clazz = Class.forName("grammar.Child");
			//2. 判斷是否應用了這個註解
			boolean hasAnno = clazz.isAnnotationPresent(DesSimple.class); 
			//3. 獲取Annotation對象
			if(hasAnno) {
				DesSimple ds = (DesSimple)clazz.getAnnotation(DesSimple.class);
				System.out.println(ds.value());
			}
			//4. 找到方法上的註解
			Method[] ms = clazz.getMethods();
			/********  第一種解析方式 ************/
			for(Method m:ms) {
				boolean isMExist = m.isAnnotationPresent(DesSimple.class);
				if(isMExist ) {
					DesSimple dsm = (DesSimple)m.getAnnotation(DesSimple.class);
					System.out.println(dsm.value());
				}
			}
			
			/************  另一種解析方式   ******************/
			for(Method m: ms) {
				Annotation[] ans = m.getAnnotations();//獲取所有註解在該方法上的註解
				for(Annotation an:ans) {
					if(an instanceof DesSimple) {
						DesSimple desSimple = (DesSimple)an;
						System.out.println(desSimple.value());
					}
				}
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章