1. 程式人生 > 實用技巧 >java反射原理與使用

java反射原理與使用

一,反射是什麼(反射是框架設計的靈魂)

1,JAVA反射機制是在執行狀態中

對於任意一個類,都能夠知道這個類的所有屬性和方法;

對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;

這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。

2,反射提供的功能:

  • 在執行時判斷任意一個物件所屬的類
  • 在執行時構造任意一個類的物件
  • 在執行時判斷任意一個類所具有的成員變數和方法
  • 在執行時呼叫任意一個物件的方法

(要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件(class)。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼檔案對應的Class型別的物件.)

3,關於class物件和這個class類

  • Class物件的由來是將class檔案讀入記憶體,併為之建立一個Class物件

4,class類 :代表一個類,是Java反射機制的起源和入口

  • 用於獲取與類相關的各種資訊, 提供了獲取類資訊的相關方法
  • Class類繼承自Object類

  • Class類是所有類的共同的圖紙

  • 每個類有自己的物件,同時每個類也看做是一個物件,有共同的圖紙Class,存放類的結構資訊,能夠通過相應方法取出相應的資訊:類的名字、屬性、方法、構造方法、父類和介面。

Class 類的例項表示正在執行的 Java 應用程式中的類和介面。也就是jvm中有N多的例項每個類都有該Class物件。(包括基本資料型別)
Class 沒有公共構造方法。Class 物件是在載入類時由 Java 虛擬機器以及通過呼叫類載入器中的defineClass 方法自動構造的。也就是這不需要我們自己去處理建立,JVM已經幫我們建立好了。

沒有公共的構造方法,方法共有64個太多了。

5,反射的使用場景

  • Java編碼時知道類和物件的具體資訊,此時直接對類和物件進行操作即可,無需反射
  • 如果編碼時不知道類或者物件的具體資訊,此時應該使用反射來實現

比如類的名稱放在XML檔案中,屬性和屬性值放在XML檔案中,需要在執行時讀取XML檔案,動態獲取類的資訊
在編譯時根本無法知道該物件或類可能屬於哪些類,程式只依靠執行時資訊來發現該物件和類的真實資訊

二,獲取反射入口(class物件)的三種方法

要想操作反射,必須先拿到反射的入口

1,通過通過Class.forName("全類名")

try {
			Class<?> perClazz = Class.forName("reflect_fanshe.Person");
			System.out.println(perClazz);
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		}

2,類名.class

Class<?> perClazz2 = Person.class;

3,物件.getClass()

Person person = new Person();
Class<?> perClazz3 = person.getClass();

三,根據反射入口物件(class)獲取類的各種資訊

可以用一個類的反射入口class物件獲取類的所有資訊

  • 例1:perClazz.getMethods() 獲取此類的所有public方法(父類的,實現介面的,自己的)
Class<?> perClazz = null;
		try {
			perClazz = Class.forName("reflect_fanshe.Person");
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		}
		Method[] methods = perClazz.getMethods();
                //遍歷所有方法
		for (Method method : methods) {
			System.out.println(method);
		}
	}

 

  • 例2:獲取所有的構造方法

 

  • 例3: 獲取父類

  • 例4:獲取當前類(只有本類的)的所有方法和屬性,包括私有的

  • 重要:可以獲取當前類的物件,並通過物件呼叫類的方法

四,通過反射獲取物件的例項,並操作物件

1,class.newInstance() ,並強轉型別,然後就可以操作物件了,主要是呼叫方法。

2,操作屬性,可以操作類裡面的public屬性和private屬性

如果屬性是private,正常情況下是不允許外界操作屬性值,這裡可以用Field類的setAccessible(true)方法,暫時開啟操作的許可權

呼叫方法也一樣,可以呼叫私有的方法,null是因為這個方法沒有引數

五,在 程式執行中,動態的決定呼叫的類,以及方法