註解:說明程序得,給計算機看的java
註釋:用文字描述程序,給程序員看的程序員
// 單行註釋 /* 多行註釋 */ /** 文檔註釋 */
註解的定義:api
註解(Annotation),也叫元數據。一種代碼級別的說明。它是 JDK1.5 及之後版本引入的一個特性,與類、接口、枚舉是在同一個層次。它能夠聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明,註釋。數組
做用分類:ide
一、編寫文檔:經過代碼裏標識的註解生成文檔【生成文檔doc文檔】spa
二、編譯檢查:經過代碼裏標識的註解讓編譯器可以實現基本的編譯檢查【Override】code
三、代碼分析:經過代碼裏標識的註解對代碼進行分析【使用反射】對象
@Override 檢查方法是否繼承父類或接口繼承
@@Deprecated 該註解表示註釋的內容過期接口
@@SuppressWarnings 壓制警告
@SuppressWarnings("all") public class AnnoDemo { @Override public String toString() { return "Demo01{}"; } @Deprecated public void show(){ //發現過期了,功能跟不上需求了 } public void showNew(){ //知足功能更增強大的方法 } public void demo(){ show(); //不推薦使用,但可使用 showNew(); Date date = new Date(); date.getYear();//不推薦使用,但可使用 } }
格式
//元註解 public @interface MyAnno{ //屬性列表 }
反編譯
javap AnnoName.class
public interface MyAnno extends java.lang.annotation.Annotation { }
註解的本質其實就是一個接口,繼承Annotation父接口
/** * 註解的本質就是接口 */ public @interface MyAnno { public String show(); }
屬性,在接口中定義的抽象方法
public @interface MyAnno { String Show1(); int show2(); String[] show3(); AnnoName show4(); PersonEnum show5(); }
一、基本數據類型
二、String 類型
三、枚舉類型
四、註解
五、以上類型的數組
public @interface MyAnno { String show1(); int show2(); String[] show3(); AnnoName show4(); PersonEnum show5(); }
默認值
若是定義的屬性時,使用default關鍵字給屬性默認初始值,能夠在使用註解是不賦值
public @interface MyAnno { String name(); int age() ; } public class Demo01 { @MyAnno(name="andy",age = 18) public void show(){ } }
public @interface MyAnno { String name(); int age() default 18; } public class Demo { @MyAnno(name="andy") public void show(){ } }
value
若是隻有一個屬性須要賦值,並且該屬性的名稱是
value
,那麼在賦值時value
能夠省略
public @interface MyAnno { String value(); } public class Demo { @MyAnno("andy") public void show(){ } }
{}
數組賦值的時候,值使用
{}
包裹,若是數組中只有一個值,那麼{}
能夠省略
public @interface MyAnno { String show1(); String[] show2();//數組一個值的時候能夠省略大括號 AnnoName show3(); PersonEnum show4(); } public class Demo01 { @MyAnno(show1="Andy",show3 = @AnnoName,show4 = PersonEnum.P1,show2 = {"a","b"}) public void show(){ } }
JDK 中給咱們提供的4個元註解
描述當前註解可以做用的位置
一、ElementType.TYPE,能夠做用在類上
二、ElementType.METHOD,能夠做用在方法上
三、ElementType.FIELD,能夠做用在成員變量上
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.FIELD}) public @interface MyAnno { } @MyAnno public class Worker { @MyAnno private String name; @MyAnno public void show(){ } }
描述註解被保留到的階段
SOURCE < CLASS < RUNTIME
一、SOURCE,表示當前註解只在代碼階段有效
二、CLASS,表示該註解會被保留到字節碼階段
三、RUNTIME,表示該註解會被保留到運行階段 JVM
//自定義的註解,通常用RUNTIME @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { }
描述註解是否被抽取到 JavaDoc api中
描述註解是否能夠被子類繼承
public class Teacher { public void show(){ System.out.println("Teacher show ...."); } } public class Student { public void show(){ System.out.println("student show ...."); } }
/** * 自定義註解 * 該註解標明要執行哪一個類中哪一個方法 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InvokAnno { String className(); String methodName(); }
@InvokAnno(className = "com.andy.anno.Student",methodName = "show") public class MyMain { public static void main(String[] args) throws Exception { //獲取類對象 Class<MyMain> clazz = MyMain.class; //獲取類對象中的註解 InvokAnno annotation = clazz.getAnnotation(InvokAnno.class); /* 註解本質是 接口 獲取到的其實時接口的實現 public class MyInvokAnno implements InvokAnno{ String className(){ return "com.andy.anno.student"; } String methodName(){ return "show"; } } */ //獲取註解中對應的屬性 String className = annotation.className(); String methodName = annotation.methodName(); System.out.println(className+" "+methodName); //經過反射的方式實現接口的功能 Class<?> aClass = Class.forName(className); Method show = aClass.getDeclaredMethod("show"); Object o = aClass.newInstance(); show.invoke(o); } }