一、什么是java注解
注解套腹,顧名思義绪抛,注解,就是對(duì)某一事物進(jìn)行添加注釋說(shuō)明,會(huì)存放一些信息电禀,這些信息可能對(duì)以后某個(gè)時(shí)段來(lái)說(shuō)是很有用處的。
Java注解又叫Java標(biāo)注笤休,java提供了一套機(jī)制尖飞,使得我們可以對(duì)方法、類、參數(shù)政基、包贞铣、域以及變量等添加標(biāo)準(zhǔn)(即附上某些信息)。且在以后某個(gè)時(shí)段通過(guò)反射將標(biāo)注的信息提取出來(lái)以供使用沮明。
二辕坝、自定義Java標(biāo)注
1 為什么要自定義注解
Java從1.5版本以后默認(rèn)內(nèi)置三個(gè)標(biāo)注:
@Override:只能用在方法之上的,用來(lái)告訴別人這一個(gè)方法是改寫父類的荐健。
@Deprecated:建議別人不要使用舊的API的時(shí)候用的,編譯的時(shí)候會(huì)用產(chǎn)生警告信息,可以設(shè)定在程序里的所有的元素上.
@SuppressWarnings:這一個(gè)類型可以來(lái)暫時(shí)把一些警告信息消息關(guān)閉.
但是酱畅,僅僅這三個(gè)標(biāo)注是不能滿足我們開(kāi)發(fā)時(shí)一些需求的。所以java允許我們自定義注解來(lái)使用江场。
2 如何自定義注解
自定義步驟大致分為兩步:
1 > 通過(guò)@interface關(guān)鍵字(注意纺酸,不是interface,是@interace)聲明注解名稱址否,以及注解的成員屬性或者叫做注解的參數(shù)餐蔬。
2 >使用Java內(nèi)置的四個(gè)元注解對(duì)這個(gè)自定義標(biāo)注的功能和范圍進(jìn)行一些限制
問(wèn)題來(lái)了,什么是元注解佑附?
3 >什么是元注解
元注解樊诺,就是定義注解的注解,也就是說(shuō)這些元注解是的作用就是專門用來(lái)約束其它注解的注解音同。請(qǐng)區(qū)別上面那三個(gè)注解词爬,他們也是通過(guò)元注解定義而來(lái)的。
元注解有哪些呢瘟斜,主要有四個(gè)@Target,@Retention,@Documented,@Inherited缸夹?
1. * 元注解有:@Target,@Retention,@Documented,@Inherited
2. * @Target 表示該注解用于什么地方,可能的 ElemenetType 參數(shù)包括:
3. * ElemenetType.CONSTRUCTOR 構(gòu)造器聲明
4. * ElemenetType.FIELD 域聲明(包括 enum 實(shí)例)
5. * ElemenetType.LOCAL_VARIABLE 局部變量聲明
6. * ElemenetType.METHOD 方法聲明
7. * ElemenetType.PACKAGE 包聲明
8. * ElemenetType.PARAMETER 參數(shù)聲明
9. * ElemenetType.TYPE 類螺句,接口(包括注解類型)或enum聲明
10. * @Retention 表示在什么級(jí)別保存該注解信息虽惭。可選的 RetentionPolicy 參數(shù)包括:
11. * RetentionPolicy.SOURCE 注解將被編譯器丟棄
12. * RetentionPolicy.CLASS 注解在class文件中可用蛇尚,但會(huì)被VM丟棄
13. * RetentionPolicy.RUNTIME VM將在運(yùn)行期也保留注釋芽唇,因此可以通過(guò)反射機(jī)制讀取注解的信息。
14. * @Documented 將此注解包含在 javadoc 中
15. * @Inherited 允許子類繼承父類中的注解
4 自定義及使用注解示例
自定義一個(gè)類級(jí)別的標(biāo)注Description
package lighter.javaeye.com;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//這個(gè)標(biāo)注應(yīng)用于類
@Retention(RetentionPolicy.RUNTIME)//標(biāo)注會(huì)一直保留到運(yùn)行時(shí)
@Documented//將此注解包含在javadoc中
public @interface Description {
String value();
}
再定義個(gè)方法級(jí)別的注解Name
package lighter.javaeye.com;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注意這里的@Target與@Description里的不同,參數(shù)成員也不同
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
String originate();
String community();
}
然后使用以上兩個(gè)注解
package lighter.javaeye.com;
@Description(value = "javaeye,做最棒的軟件開(kāi)發(fā)交流社區(qū)")
public class JavaEyer {
@Name(originate = "創(chuàng)始人:robbin", community = "javaEye")
public String getName()
{
return null;
}
@Name(originate = "創(chuàng)始人:江南白衣", community = "springside")
public String getName2()
{
return "借用兩位的id一用,寫這一個(gè)例子,請(qǐng)見(jiàn)諒!";
}
}
說(shuō)明:其中標(biāo)注“@Description(value="javaeye,做最棒的軟件開(kāi)發(fā)交流社區(qū)")”取劫,可以寫成“@Description("javaeye,做最棒的軟件開(kāi)發(fā)交流社區(qū)") ”匆笤,結(jié)果也是一樣的。因?yàn)镈escription標(biāo)注定義的時(shí)候其參數(shù)(或者說(shuō)屬性)為value谱邪。而value比較特殊炮捧,它在被指定參數(shù)的時(shí)候可以不用顯示的寫出來(lái)。當(dāng)然如果定義的時(shí)候參數(shù)名不是value而是其它的比如des惦银,那么使用注解的時(shí)候咆课,必須顯示寫出參數(shù)名末誓,然后再賦值:@Description(Des=”xxx”)
提取出注解的信息
package lighter.javaeye.com;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class TestAnnotation {
/**
* author lighter
* <p>
* 說(shuō)明:具體關(guān)天Annotation的API的用法請(qǐng)參見(jiàn)javaDoc文檔
*/
public static void main(String[] args) throws Exception {
String CLASS_NAME = "lighter.javaeye.com.JavaEyer";
Class test = Class.forName(CLASS_NAME);
Method[] method = test.getMethods();
boolean flag = test.isAnnotationPresent(Description.class);
if (flag)
{
Description des = (Description) test.getAnnotation(Description.class);
System.out.println("描述:" + des.value());
System.out.println("-----------------");
}
//把JavaEyer這一類有利用到@Name的全部方法保存到Set中去
Set set = new HashSet();
for (int i = 0; i
{
boolean otherFlag = method[i].isAnnotationPresent(Name.class);
if (otherFlag) set.add(method[i]);
}
for (Method m : set)
{
Name name = m.getAnnotation(Name.class);
System.out.println(name.originate());
System.out.println("創(chuàng)建的社區(qū):" + name.community());
}
}
}
注意事項(xiàng):
所有的Annotation會(huì)自動(dòng)繼承java.lang.annotation這一個(gè)接口,所以不能再去繼承別的類或是接口.
最重要的一點(diǎn),Annotation類型里面的參數(shù)該怎么設(shè)定:
第一,只能用public或默認(rèn)(default)這兩個(gè)訪問(wèn)權(quán)修飾.例如,String value();這里把方法設(shè)為defaul默認(rèn)類型.
第二,參數(shù)成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數(shù)據(jù)類型和String,Enum,Class,annotations等數(shù)據(jù)類型,以及這一些類型的數(shù)組.例如,String value();這里的參數(shù)成員就為String.