注解目前非常的流行,很多主流框架都支持注解试躏,而且自己編寫代碼的時(shí)候也會(huì)盡量的去用注解,一時(shí)方便设褐,而是代碼更加簡(jiǎn)潔颠蕴。
注解的語法比較簡(jiǎn)單,除了@符號(hào)的使用之外助析,它基本與Java固有語法一致犀被。Java SE5內(nèi)置了三種標(biāo)準(zhǔn)注解:
@Override,表示當(dāng)前的方法定義將覆蓋超類中的方法外冀。
@Deprecated寡键,使用了注解為它的元素編譯器將發(fā)出警告,因?yàn)樽⒔釦Deprecated是不贊成使用的代碼雪隧,被棄用的代碼西轩。
@SuppressWarnings员舵,關(guān)閉不當(dāng)編譯器警告信息。
上面這三個(gè)注解多少我們都會(huì)在寫代碼的時(shí)候遇到藕畔。Java還提供了4中注解马僻,專門負(fù)責(zé)新注解的創(chuàng)建。
注解 | 描述 |
---|---|
@Target | 表示該注解可以用于什么地方注服,可能的ElementType參數(shù)有:CONSTRUCTOR:構(gòu)造器的聲明韭邓、FIELD:域聲明(包括enum實(shí)例)、LOCAL_VARIABLE:局部變量聲明祠汇、METHOD:方法聲明仍秤、PACKAGE:包聲明、PARAMETER:參數(shù)聲明可很、TYPE:類诗力、接口(包括注解類型)或enum聲明 |
@Retention | 表示需要在什么級(jí)別保存該注解信息∥铱伲可選的RetentionPolicy參數(shù)包括:SOURCE:注解將被編譯器丟棄苇本、CLASS:注解在class文件中可用,但會(huì)被VM丟棄菜拓、RUNTIME:VM將在運(yùn)行期間保留注解瓣窄,因此可以通過反射機(jī)制讀取注解的信息。 |
@Document | 將注解包含在Javadoc中 |
@Inherited | 允許子類繼承父類中的注解 |
定義一個(gè)注解的方式:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
除了@符號(hào)纳鼎,注解很像是一個(gè)接口俺夕。定義注解的時(shí)候需要用到元注解,上面用到了@Target和@RetentionPolicy贱鄙,它們的含義在上面的表格中已近給出劝贸。
在注解中一般會(huì)有一些元素以表示某些值。注解的元素看起來就像接口的方法逗宁,唯一的區(qū)別在于可以為其制定默認(rèn)值映九。沒有元素的注解稱為標(biāo)記注解,上面的@Test就是一個(gè)標(biāo)記注解瞎颗。
注解的可用的類型包括以下幾種:所有基本類型件甥、String、Class哼拔、enum引有、Annotation、以上類型的數(shù)組形式倦逐。元素不能有不確定的值轿曙,即要么有默認(rèn)值,要么在使用注解的時(shí)候提供元素的值。而且元素不能使用null作為默認(rèn)值导帝。注解在只有一個(gè)元素且該元素的名稱是value的情況下,在使用注解的時(shí)候可以省略“value=”穿铆,直接寫需要的值即可您单。
下面看一個(gè)定義了元素的注解。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public String id();
public String description() default "no description";
}
定義了注解荞雏,必然要去使用注解虐秦。
public class PasswordUtils {
@UseCase(id = 47, description = "Passwords must contain at least one numeric")
public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UseCase(id = 48)
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
}
}
使用注解最主要的部分在于對(duì)注解的處理,那么就會(huì)涉及到注解處理器凤优。
從原理上講悦陋,注解處理器就是通過反射機(jī)制獲取被檢查方法上的注解信息,然后根據(jù)注解元素的值進(jìn)行特定的處理筑辨。
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if (uc != null) {
System.out.println("Found Use Case:" + uc.id() + " "
+ uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for (int i : useCases) {
System.out.println("Warning: Missing use case-" + i);
}
}
Found Use Case:47 Passwords must contain at least one numeric
Found Use Case:48 no description
Warning: Missing use case-49
Warning: Missing use case-50