注解(Annotation),也叫元數(shù)據(jù)。一種代碼級別的說明。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來對這些元素進(jìn)行說明,注釋,解釋或提示。能提高程序代碼的可讀性,以便于以后的參考、修改。注釋是解釋性文本,在運行程序時,會被程序跳過,不做處理。
1、生成文檔。這是最常見的,也是Java 最早提供的注解。常用的有@see @param @return 等。
2、跟蹤代碼依賴性,實現(xiàn)替代配置文件功能。比較常見的是spring 2.5 開始的基于注解配置。作用就是減少配置。現(xiàn)在的框架基本都使用了這種配置來減少配置文件的數(shù)量。以后java的程序開發(fā),最多的也將實現(xiàn)注解配置,具有很大用處。
3、在編譯時進(jìn)行格式檢查。如@override 放在方法前,如果你這個方法并不是覆蓋了超類方法,則編譯時就能檢查出。
public @interface 注解的名字 {
變量的類型 變量的名字();
變量的類型 變量的名字() default 默認(rèn)值;
}
1、如果注解中只有一個變量需要賦值,并且這個變量的名字叫value,'value= '可以省略,直接寫值。
2、如果注解是數(shù)組類型,并且只賦值一個值,{}可以省略;如果賦值多個,則必須使用{......}。
3、如果注解中有多個變量,且沒有默認(rèn)值,使用時,必須全部賦值;如果有默認(rèn)值,使用時,有默認(rèn)值可以賦值,也可以不賦值。
1、常見注解
a) @Override,表示當(dāng)前的方法定義將覆蓋超類中的方法。
b)@Deprecated,使用了注解為它的元素編譯器將發(fā)出警告,因為注解@Deprecated是不贊成使用的代碼,被棄用的代碼。
c) @SuppressWarnings,關(guān)閉不當(dāng)編譯器警告信息。
i.deprecation,使用了過時的類戒方法時的警告。
ii.unchecked,執(zhí)行了未檢查的轉(zhuǎn)換時的警告。
iii.fallthrough,當(dāng) Switch 程序塊直接通往下一種情況而沒有 Break 時的警告等等。
2、編寫文檔:通過代碼里標(biāo)識的元數(shù)據(jù)生成文檔【生成文檔doc文檔】
a) @Param 注釋的時候使用,在其它地方調(diào)用時有提示。

b) @Documented 讓注解在導(dǎo)出的文檔中顯示。
首先看怎么導(dǎo)出文檔:選中要導(dǎo)出成文檔的項目->project->Generate Javadoc…

單擊next->next->finish。
當(dāng)在注解的前面加上@Documented,該注解就會生成在文檔中。

導(dǎo)出文檔,如果亂碼: javadoc -encoding UTF-8 -charset UTF-8。
3、代碼分析:通過代碼里標(biāo)識的元數(shù)據(jù)對代碼進(jìn)行分析【使用反射】
c) @Target,限定注解可以放的位置。
@Target(
{
TYPE, 放在類的頭部
FIELD, 放在字段的頭部
METHOD, 放在方法的頭部
PARAMETER, 放在參數(shù)的頭部
CONSTRUCTOR, 放在構(gòu)造器的頭部
LOCAL_VARIABLE 放在局部變量的頭部
}
)
d)@Retention,限定注解的生命周期。source(只在java源碼時候有效,編譯之后失效),class(只在編譯時有效),runtime(運行時有效,最常用的)。
e) 自定義一些功能注解。
示例:
package cn.com.javazysq.test1;
/**
* 自定義注解
* 這個注解里有三個變量,其中id已經(jīng)有默認(rèn)值了
*/
public @interface MyAnnotation {
//private int id() default 110; 錯誤的,only public & abstract are permitted
int id() default 110;
String name() default 'abc';
float value();
}
package cn.com.javazysq.test1;
/**
* 自定義注解
*/
public @interface MyAnnotation2 {
int id() default 110;
String name() default 'abc';
float[] value();
}
package cn.com.javazysq.test1;
/**
* 自定義注解
*/
public @interface MyAnnotation3 {
int id() default 110;
String name() default 'abc';
Sex[] value();
}
package cn.com.javazysq.test1;
/**
* 自定義注解
* 只能放在方法的頭部
* 只有在運行的時候才有效果
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation4 {
int id() default 110;
}
package cn.com.javazysq.test1;
public enum Sex {
男,女
}
//測試@Param...
package cn.com.javazysq.test1;
public class AnnotationTest {
public static void main(String[] args) {
User u= new User(1, '');
u.sum(1, 2);
}
}
package cn.com.javazysq.test1;
@MyAnnotation(name='張三',value = 59.9F)
public class User {
@MyAnnotation(name='張三',value = 59.9F)
private int id;
private String name;
public int getId() {
return id;
}
@MyAnnotation(59.9F)
@MyAnnotation2(value={1,2,3})
@MyAnnotation3(Sex.女)
@MyAnnotation4()
public void setId(int id) {
this.id = id;
}
@MyAnnotation2(1)
public String getName() {
return name;
}
@MyAnnotation3(value={Sex.女,Sex.男})
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return super.toString();
}
/**
* 構(gòu)造方法
* @param id 編號
* @param name 名字
*/
public User(int id, String name) {
this.id = id;
this.name = name;
}
/**
* 求和
* @param a 數(shù)字1
* @param b 數(shù)字2
* @return 兩個數(shù)字的和
*/
public int sum(int a,int b){
return a+b;
}
}
登陸案例,見代碼:
package cn.com.javazysq.test2;
/**
* 自定義注解
* 限定:
* 1.只能放在方法的頭部
* 2.只能在運行時有效
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginAnnotation {
String name();
String pwd();
}
package cn.com.javazysq.test2;
public class UserService {
@LoginAnnotation(name='bochy',pwd='123dd')
public boolean login(String name,String pwd){
if('bochy'.equals(name)&&'123'.equals(pwd)){
return true;
}else{
return false;
}
}
}
package cn.com.javazysq.test2;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
String className='cn.com.bochy.test2.UserService';
String methodName = 'login';
/*獲取運行時對象*/
Class c = Class.forName(className);
/*調(diào)用無參的構(gòu)造方法實例化對象*/
Object obj = c.newInstance();
/*獲取方法對象*/
Method m = c.getMethod(methodName, String.class,String.class);
//獲取注解
LoginAnnotation loginAnnotation = m.getAnnotation(LoginAnnotation.class);
if(loginAnnotation==null){
System.out.println('沒有找到注解');
return;
}
//獲取注解里的值
String name = loginAnnotation.name();
String pwd = loginAnnotation.pwd();
//調(diào)用方法
boolean ret = (boolean) m.invoke(obj, name,pwd);
System.out.println(ret);
}
}