天天都在用注解,那你知道Java注解的基本原理嗎?
作者:空谷幽瀾
cnblogs.com/huajiezh/p/5263849.html
注解目前非常的流行,很多主流框架都支持注解,而且自己編寫(xiě)代碼的時(shí)候也會(huì)盡量的去用注解,一時(shí)方便,而是代碼更加簡(jiǎn)潔。
注解的語(yǔ)法比較簡(jiǎn)單,除了@符號(hào)的使用之外,它基本與Java固有語(yǔ)法一致。Java SE5內(nèi)置了三種標(biāo)準(zhǔn)注解:
@Override,表示當(dāng)前的方法定義將覆蓋超類中的方法。
@Deprecated,使用了注解為它的元素編譯器將發(fā)出警告,因?yàn)樽⒔釦Deprecated是不贊成使用的代碼,被棄用的代碼。
@SuppressWarnings,關(guān)閉不當(dāng)編譯器警告信息。
上面這三個(gè)注解多少我們都會(huì)在寫(xiě)代碼的時(shí)候遇到。Java還提供了4中注解,專門(mén)負(fù)責(zé)新注解的創(chuàng)建。
定義一個(gè)注解的方式:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public?@interface?Test?{
??
}
除了@符號(hào),注解很像是一個(gè)接口。定義注解的時(shí)候需要用到元注解,上面用到了@Target和@RetentionPolicy,它們的含義在上面的表格中已近給出。
在注解中一般會(huì)有一些元素以表示某些值。注解的元素看起來(lái)就像接口的方法,唯一的區(qū)別在于可以為其制定默認(rèn)值。沒(méi)有元素的注解稱為標(biāo)記注解,上面的@Test就是一個(gè)標(biāo)記注解。推薦:SpringBoot核心注解原理,這些都是要熟知的!
注解的可用的類型包括以下幾種:所有基本類型、String、Class、enum、Annotation、以上類型的數(shù)組形式。元素不能有不確定的值,即要么有默認(rèn)值,要么在使用注解的時(shí)候提供元素的值。而且元素不能使用null作為默認(rèn)值。
注解在只有一個(gè)元素且該元素的名稱是value的情況下,在使用注解的時(shí)候可以省略“value=”,直接寫(xiě)需要的值即可。
下面看一個(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ì)涉及到注解處理器。
從原理上講,注解處理器就是通過(guò)反射機(jī)制獲取被檢查方法上的注解信息,然后根據(jù)注解元素的值進(jìn)行特定的處理。
public?static?void?main(String[]?args)?{
?????List?useCases?=?new?ArrayList();
?????Collections.addAll(useCases,?47,?48,?49,?50);
?????trackUseCases(useCases,?PasswordUtils.class);
?}
?
?public?static?void?trackUseCases(List?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
上面的三段代碼結(jié)合起來(lái)是一個(gè)跟蹤項(xiàng)目中用例的簡(jiǎn)單例子。
