Java註解與反射學習筆記

Zhou.Y.M發表於2020-12-21

一、註解

1、概念

註解就是原始碼的後設資料,通熟的講就是程式碼中的標籤。

java中註解主要用於標記程式碼,或結合其他方法,如反射,實現值的傳遞。另外,註解在框架中也使用較多。

java中有7種自帶的註解,包括@Override, @Deprecated, @SuppressWornings 和四種元註解(表示註解的註解)。jdk7後,逐步增加為10種。

(1)按來源分

  • JDK 自帶註解;

  • 第三方註解,如Spring框架中的RequestMapping註解等;

  • 自定義註解,使用 @interface 關鍵字定義。

(2)按生命週期劃分

  • SOURCE:只存在於原始碼中,編譯成 class 檔案就不存在了。

  • Class:存在於原始碼中和 class 檔案中。

  • RUNTIME:註解保留到執行時。

2、java中自帶的註解

(1)三種基本註解

  • @Override - 檢查該方法是否是重寫方法。如果發現其父類,或者是引用的介面中並沒有該方法時,會報編譯錯誤。
  • @Deprecated - 標記過時方法。如果使用該方法,會報編譯警告。
  • @SuppressWarnings - 指示編譯器去忽略註解中宣告的警告。

(2)四種元註解

  • @Retention - 標識這個註解怎麼儲存,是隻在程式碼中,還是編入class檔案中,或者是在執行時可以通過反射訪問(即屬於前面定義的三種生命週期中的哪一種)。
  • @Documented - 標記這些註解是否包含在使用者文件中。
  • @Target - 標記這個註解應該是哪種 Java 成員。
  • @Inherited - 標記這個註解是繼承於哪個註解類(預設 註解並沒有繼承於任何類)

(3)新增註解
從 Java 7 開始,額外新增了 3 個註解:

  • @SafeVarargs - Java 7 開始支援,忽略任何使用引數為泛型變數的方法或建構函式呼叫產生的警告。
  • @FunctionalInterface - Java 8 開始支援,標識一個匿名函式或函式式介面。
  • @Repeatable - Java 8 開始支援,標識某註解可以在同一個宣告上使用多次。

在java自帶的註解中,我在練習中使用到最多的是@Override和@Retention。

3、自定義註解

自定義註解的關鍵字為@interface,且修飾符必須為public而不能為其它,不寫則預設為public。


public @interface Info {
    String value() default "ZhouYM";
    int score();
}

上面一段自定義註解的程式碼表示建立了@Info這一註解,其中第一個引數為value,預設值為ZhouYM;第二個引數為isDelete。在使用的時候,沒有寫預設值的引數必須傳值。

二、反射

1、概念

反射是java中的高階特性,指的是程式在執行期間藉助反射 API 取得任何類的內部資訊,並通過這些內部資訊去操作對應物件的內部屬性和方法。

任何一個類,在第一次使用時,就會被 JVM 載入到堆記憶體的方法區中。JVM 載入類成功後,就會在方法區中產生一個對應的 Class 物件(一個類只要一個 Class 物件),這個 Class 物件包含被載入類的全部結構資訊。反射本質上就是通過反編譯的方式獲取這個class物件,並進行與類有關的操作,如新建物件等。

反射給Java帶來了一些動態性,且可以獲得類在JVM中的很多資訊,可以做到很多其他方法不能完成的事。反射可以和註解一起使用,這是用new等方法所不能做到的,同時將類名寫入配置檔案,從配置檔案中獲取時,也需要用到反射的方法獲取類進而建立物件,而不能用new的方法例項化。

2、反射中的常用函式

  • Class.forName(“具體類名”),用於獲取類
  • 類.newInstance(),用於建立前面獲取的類的新物件
  • c.getConstructors(),使用類的建構函式
  • Method md = 類物件.getMethod(“類中的公有方法名”),用於獲取共有方法
  • Method dm = 類物件.getDeclaredMethod(“類中的私有方法名”),用於獲取該類的所有方法
  • Object obj1 = md.invoke(in,“ZhouYM”),使用方法
  • Field names = 類物件.getField(“成員變數名”),獲取公有成員變數
  • Field names = 類物件.getDeclaredField(“成員變數名”);af.setAccessible(true);,獲取所有成員變數

3、反射的簡單例項

(1)forName和getDeclaredMethod的簡單使用


public static void main(String[] args) throws Exception {
		
		Class clazz = Class.forName("org.Reflection.User");
		Method methods = clazz.getDeclaredMethod("getName");
		dm.setAccessible(true);//設定私有方法可訪問
		Object obj = dm.invoke(u2);
		
		System.out.println(obj);
	}
 
}

(2)forName和getDeclaredField的簡單使用


public class Demo {
	
	public static void main(String[] args) throws Exception {
		
		Class clazz = Class.forName("org.Reflection.User");
		Object obj = clazz.newInstance();	
		Field nf = clazz.getDeclaredField("name");
		nf.setAccessible(true);//設定私有變數可訪問
		nf.set(obj, "ZhouYM");
		Object object = nf.get(obj);
		
		System.out.println(object);
	}
 
}

三、總結

以上便是我在學習了註解和反射,並做了一些簡單練習後的學習筆記。今後我會嘗試將註解和反射結合在一起使用,並繼續更加深入的學習,瞭解它們更為深入的原理,並在實際開發和練習過程中多多使用。

相關文章