Java注解
Spring中用到了Java注解,可Java注解究竟是怎么一回事呢领迈?
什么是注解
注解用一個(gè)詞來描述就是元數(shù)據(jù)彻磁,即一種描述數(shù)據(jù)的數(shù)據(jù)。比如我們經(jīng)常使用@Override
注解來標(biāo)注被重寫的方法狸捅,可是衷蜓,即使我們不使用注解標(biāo)注,程序也可以正確執(zhí)行呀尘喝,那為什么還要注解呢磁浇。
事實(shí)上,@Override
告訴編譯器這個(gè)方法是一個(gè)重寫方法(描述方法的元數(shù)據(jù))朽褪,如果父類中不存在該方法置吓,編譯器便會報(bào)錯(cuò),提示該方法沒有重寫父類中的方法缔赠。如果我不小心拼寫錯(cuò)誤衍锚,例如將toString()
寫成了toStrring(){double r}
,而且我也沒有使用@Override
注解嗤堰,那程序依然能編譯運(yùn)行戴质。但運(yùn)行結(jié)果會和我期望的大不相同。現(xiàn)在我們了解了什么是注解,并且使用注解有助于閱讀程序告匠。
在項(xiàng)目配置方面戈抄,注解會于代碼相連。假如你想為應(yīng)用設(shè)置很多的常量或參數(shù)后专,這種情況下划鸽,XML是一個(gè)很好的選擇,因?yàn)樗粫囟ǖ拇a相連行贪。如果你想把某個(gè)方法聲明為服務(wù)漾稀,那么使用Annotation會更好一些,因?yàn)檫@種情況下需要注解和方法緊密耦合起來建瘫,開發(fā)人員也必須認(rèn)識到這點(diǎn)崭捍。
Java SE5內(nèi)置的三種標(biāo)準(zhǔn)注解
@Override
重寫
@Deprecated
為它的元素編譯發(fā)出警告,表示這是不贊成使用啰脚,被棄用的代碼
@SuppressWarning
關(guān)閉不當(dāng)編譯警告信息
創(chuàng)建新注解
Java提供了4種注解殷蛇,負(fù)責(zé)創(chuàng)建新注解
-
@Documented
將注解包含在JavaDoc中 -
@Retention
表示需要在什么級別保存該注解信息¢吓ǎ可選的RetentionPolicy參數(shù)包括:
SOURCE:注解將被編譯器丟棄
CLASS:注解在class文件中可用粒梦,但會被VM丟棄
RUNTIME:VM將在運(yùn)行期間保留注解,因此可以通過反射機(jī)制讀取注解的信息荸实。 -
@Target
注解用于什么地方
可能的ElementType參數(shù)有:
CONSTRUCTOR:構(gòu)造器的聲明
FIELD:域聲明(包括enum實(shí)例)
LOCAL_VARIABLE:局部變量聲明
METHOD:方法聲明
PACKAGE:包聲明
PARAMETER:參數(shù)聲明
TYPE:類匀们、接口(包括注解類型)或enum聲明 -
@Inherited
允許子類繼承該注解
Example
- 定義一個(gè)注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public String id();
public String description() default "no description";
}
在注解中一般會有一些元素以表示某些值。注解的元素看起來就像接口的方法准给,唯一的區(qū)別在于可以為其制定默認(rèn)值泄朴。沒有元素的注解稱為標(biāo)記注解
注解的可用的類型包括以下幾種:所有基本類型、String露氮、Class祖灰、enum、Annotation畔规、以上類型的數(shù)組形式局扶。元素不能有不確定的值,即要么有默認(rèn)值叁扫,要么在使用注解的時(shí)候提供元素的值三妈。而且元素不能使用null作為默認(rèn)值。注解在只有一個(gè)元素且該元素的名稱是value的情況下莫绣,在使用注解的時(shí)候可以省略“value=”沈跨,直接寫需要的值即可。
- 使用注解
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();
}
}
- 對注解進(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);
}
}
----------------------------------
運(yùn)行結(jié)果
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