注解相當於一種標記,在程序中加了注解就等於為程序打上了某種標記,沒加,則等於沒有某種標記。
以后,javac編譯器,開發工具和其他程序可以用反射來了解你的類及各種元素上有無何種標記,看你有什么標記,就去干相應的事。
標記可以加在包,類,字段,方法,方法的參數以及局部變量上。
一個注解相當於一個類。
看java.lang包,可看到JDK中提供的最基本的annotation。
@SuppressWarning(”deprecation”)--->壓制警告
SupressWarning是告知編譯器或開發工具等提示指定的編譯器警告;
“deprecation”是告知具體的信息即方法已過時。
@Deprecated(過時的方法,對於不再使用的方法,可能別人或別的地方有調用這個方法,不能刪除完事)
直接在剛才的類中增加一個方法,並加上@Deprecated標注,在另外一個類中調用這個方法。測試一下。
@SuppressWarnings("deprecation") (用這個可以告訴 程序說,我知道調用的方法過時了)
@Override--->提示覆蓋(父類方法)
public boolean equals(Reflect other)方法與HashSet結合講解
像person類,覆蓋父類的equals 和hashCode方法,人家接收的參數是Object,人們習慣總是傳入自己的對象,造成覆蓋失敗,變成重載!
注解的應用結構圖
演示和講解@Target元注解
Target(告訴編譯器,自定義的注解類可以用在方法還是類....),設置Target等於ElementType.METHOD,原來加在類上的注解就報錯了,改為用數組方式設置{ElementType.METHOD,ElementType.TYPE}就可以了。
元注解以及其枚舉屬性值不用記,只要會看jdk提供那幾個基本注解的API幫助文檔的定義或其源代碼,按圖索驥即可查到,或者直接看java.lang.annotation包下面的類。
(自定義注解)示例代碼:
@Retention(RetentionPolicy.RUNTIME)//告訴程序說,這個注解要保存到運行時期
@Target({ElementType.METHOD,ElementType.TYPE})//告訴編譯器,這個注解可以用在方法上,也可以用在類上
public @interface MyAnnotation {
String color() default "yellow";//默認缺省值為yellow
String value() ;//不指定
int [] arrayAttr() default {1,2};//默認為{1,2}
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;//枚舉類
MetaAnnotation annotationAttr() default @MetaAnnotation("xxx");//屬性中加注解,用@。可以在對別的類加注解時,改變值
}
為注解增加基本屬性
(可以是八種基本數據類型,String ,數組,枚舉,注解,Class)
什么是注解的屬性?
一個注解相當於一個胸牌,如果你胸前貼了胸牌,就是傳智播客的學生,否則,就不是。如果還想區分出是傳智播客哪個班的學生,這時候可以為胸牌在增加一個屬性來進行區分。加了屬性的標記效果為:@MyAnnotation(color="red")
定義基本類型的屬性和應用屬性:
在注解類中增加String color();
@MyAnnotation(color="red")
用反射方式獲得注解對應的實例對象后,再通過該對象調用屬性對應的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以認為上面這個@MyAnnotation是MyAnnotaion類的一個實例對象
如果注解中有一個名稱為value的屬性,且你只想設置value屬性(即其他屬性都采用默認值或者你只有一個value屬性),那么可以省略value=部分,例如:@MyAnnotation("lhm")。
枚舉和注解都是特殊的類,不能用new 創建它們的實例對象,創建枚舉的實例對象就是在其中增加元素。
在程序中如何創建出一個注解的實例對象啊?直接用@放上一個標記即可
Eg:package july78javaEnhance;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)//元注解:信息的信息就是元信息 RUNTIME,保留到運行期間
/**
* 指示注釋類型的注釋要保留多久。如果注釋類型聲明中不存在 Retention 注釋,
* 則保留策略默認為 RetentionPolicy.CLASS。
*/
//@Target(ElementType.METHOD)如果加上這句的話(只能作用於方法),那邊就會報錯!
public @interface AnnotationDemo12 {//注解
String color() default "blue";//相當於構造方法一樣,如果給了它默認的初值,可以不用再設置(有默認的)
String value();
int []age();//數組和枚舉類型的注解
//還有注解類型的注解,暫時沒學會
MetaAnnotation annotation();
//上面的MetaAnnotation是自己定義的一個注解類型,這樣的話對於應用了當前注解的AnnotationDemo11類,就必須寫上注解類型的屬性
}
package july78javaEnhance;
import java.util.Arrays;
//備注:應用注解后,它的屬性你你沒有寫上,它會給予提醒!missing attribution
@AnnotationDemo12(color = "red",value = "j2ee",age = {1,2,3}, annotation = @MetaAnnotation(sex = "男"))//注解加注解
public class AnnotationDemo11 {
@SuppressWarnings("deprecation")//壓縮注解,一個注解就是一個類,用到的一個注解就相當於是調用的實例對象
@AnnotationDemo12(value = "jase",age = {1,2,3}, annotation = @MetaAnnotation(sex = "女"))//備注:如果別的屬性有默認值,只有一個屬性需要你設置,那么你就不需要寫上全部的
//賦值表達式,如上直接寫上"jase"就行
public static void main(String[] args) {
System.runFinalizersOnExit(true);//表示已經過時的方法,開發工具會給它中間加上一天橫線
/**
* boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定類型的注釋存在於此元素上,則返回 true,否則返回 false。
*/
if(AnnotationDemo11.class.isAnnotationPresent(AnnotationDemo12.class)){
AnnotationDemo12 annocation = (AnnotationDemo12)AnnotationDemo11.class
.getAnnotation(AnnotationDemo12.class);//證明這里面有你的注解
System.out.println(annocation.color());//調用屬性
System.out.println(Arrays.toString(annocation.age()));//將數組打印出來
System.out.println(annocation.annotation().sex());//相當於調用屬性的屬性
}
}
}