Python第七課--面向物件程式設計
定義
註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。
①編寫文件:通過程式碼裡標識的元資料生成文件【生成文件doc文件】
② 程式碼分析:通過程式碼裡標識的元資料對程式碼進行分析【使用反射】
③編譯檢查:通過程式碼裡標識的元資料讓編譯器能夠實現基本的編譯檢查【Override】
JDK中一些預定義的註解
@Override
@Deprecated : 該註解標註的內容,已過時
@SuppressWarnings : 該註解用來壓制警告
自定義註解
1.格式:
元註解
public @interface 註解名稱 {
屬性列表
}
2.定義註解:
建立元註解
//定義註解 元註解
public @interface MyAnno {}
進行編譯和反編譯
可以發現註解本質上就是介面,繼承了java.lang.annotation.Annotation
反編譯後的程式碼:
//定義註解 元註解 public @interface MyAnno {}
3.註解的屬性:介面中可以定義的抽象方法
要求:
1.返回值型別(只能是下列型別):
* 基本資料型別
* String型別
* 列舉型別
* 註解型別
* 以上型別的陣列
2.定義了屬性在使用時候需要給屬性賦值(未使用default關鍵字初始化值的屬性) 如果只有一個屬性需要賦值並且這個屬性名為value的話,這個key可以省去。 陣列賦值比較特殊 如果陣列只有 一個值花括號可以不寫
public @interface MyAnno { int age(); String name() default "張三"; Person per(); //Person為定義的列舉類 MyAnno2 anno2(); //MyAnno2為註解類 String[] strs(); } //使用示例: @MyAnno(age = 1,name = "李四",per = Person.PI,anno2 = @MyAnno2,strs = {"abc","cda"}) // 陣列賦值比較特殊 public class Test { }
3.元註解:用於描述註解的註解
-
@Target :描述註解能夠作用的位置
-
@Retention :描述註解被保留的階段
RetentionPolicy.RUNTIME 會儲存class檔案中,並且在執行時會被JVM讀取到
RetentionPolicy.SOURCE 不會儲存class檔案,自然也不會被JVM所讀取到
RetentionPolicy.CLASS 儲存class檔案中但是不會被JVM讀取
-
@Documented : 描述註解是否被抽取到api文件,在使用javadoc命令的時候起效
-
@Inherited : 描述註解是否被子類繼承
父類加了這個被@Inherited元註解修飾的註解那麼子類會自動繼承該註解
使用註解
案例:
package cn.itcast.annotation.demo; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 簡單的測試框架 * * 當主方法執行後,會自動自行被檢測的所有方法(加了Check註解的方法),判斷方法是否有異常,記錄到檔案中 */ public class TestCheck { public static void main(String[] args) throws IOException { //1.建立計算器物件 Calculator c = new Calculator(); //2.獲取位元組碼檔案物件 Class cls = c.getClass(); //3.獲取所有方法 Method[] methods = cls.getMethods(); int number = 0;//出現異常的次數 BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt")); for (Method method : methods) { //4.判斷方法上是否有Check註解 if(method.isAnnotationPresent(Check.class)){ //5.有,執行 try { method.invoke(c); } catch (Exception e) { //6.捕獲異常 //記錄到檔案中 number ++; bw.write(method.getName()+ " 方法出異常了"); bw.newLine(); bw.write("異常的名稱:" + e.getCause().getClass().getSimpleName()); bw.newLine(); bw.write("異常的原因:"+e.getCause().getMessage()); bw.newLine(); bw.write("--------------------------"); bw.newLine(); } } } bw.write("本次測試一共出現 "+number+" 次異常"); bw.flush(); bw.close(); } } package cn.itcast.annotation.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Check { } package cn.itcast.annotation.demo; /** * 小明定義的計算器類 */ public class Calculator { //加法 @Check public void add(){ String str = null; str.toString(); System.out.println("1 + 0 =" + (1 + 0)); } //減法 @Check public void sub(){ System.out.println("1 - 0 =" + (1 - 0)); } //乘法 @Check public void mul(){ System.out.println("1 * 0 =" + (1 * 0)); } //除法 @Check public void div(){ System.out.println("1 / 0 =" + (1 / 0)); } public void show(){ System.out.println("永無bug..."); } }