java反射詳解---反射的理論知識
阿新 • • 發佈:2019-02-08
此篇主要講解下反射的理論概念,另外一篇則是有很多的實際反射的例子,連結如下:
一、JAVA是動態語言嗎?
一般而言,說到動態言,都是指在程式執行時允許改變程式結構或者變數型別,從這個觀點看,JAVA和C++一樣,都不是動態語言。
但JAVA它卻有著一個非常突出的動態相關機制:反射。通過反射,Java可以於執行時載入、探知和使用編譯期間完全求和的類、生成其物件實體,呼叫其方法或者對屬性設值。所以Java算是一個半動態的語言吧。
反射的概念:
在Java中的反射機制是指在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;
對於任意一個物件,都能夠呼叫它的任意一個方法;
這種動態獲取資訊以及動態呼叫物件方法的功能稱為Java語言的反射機制
二、動態性質
2.1、動態性質
- 執行時生成物件例項;
- 執行期間呼叫方法;
- 執行時更改屬性
2.2、Java反射機制能實現的功能
- 在執行時判斷任意一個物件所屬的類
- 在執行時構造任意一個類的物件
- 在執行時判斷任意一個類所具有的方法和屬性
- 在執行時呼叫任意一個物件的方法
- 生成動態代理
2.3、Java反射應用場合
在Java程式中許多物件在執行時都會出現兩種型別:編譯時型別和執行時型別
編譯時的型別由宣告該物件時使用的型別決定,執行時的型別由實際賦給物件的型別決定
如:
Person p =new Student();
編譯時型別為Person,而執行時為Student
除此之外,程式在執行時還可能接收到外部傳入的一個物件,該物件的編譯時型別為Object,但程式又需要呼叫該物件執行時型別的方法。為了這些問題程式需要在執行時發現物件和類的真實資訊。然而,如果編譯時根本無法預知該物件和類可能屬於哪些類,程式只依靠執行時資訊來發現該物件和類的真實資訊,此時就必須使用反射
三、Java反射API
反射API用來生成在當前JAVA虛擬機器中的類、介面或者物件的資訊。
- Class類:反射的核心類,可以獲取類的屬性,方法等內容資訊。
- Field類:Java.lang.reflect.表示類的屬性,可以獲取和設定類的中屬性值。
- Method類:Java.lang.reflect。表示類的方法,它可以用來獲取類中方法的資訊或者執行方法
- Construcor類:Java.lang.reflect。表示類的構造方法。
四、獲取Class物件方式
- 呼叫某個物件的getClass()方法
Person p = new Person(); Class cla=p.getClass();
- 呼叫某個類的class屬性來獲取該類對應的Class物件
Class cls=Person.class;
- 使用Class類的forName()靜態方法
Class cla=Class.forName(“類的全路徑”);
附上程式碼示例:
package com.fusionskye.ezsonar.model.configcenter;
import com.fusionskye.ezsonar.model.stream.StreamRule;
import java.io.IOException;
class hello {
public static void main(String[] a) throws IOException {
// 1.利用物件呼叫getClass()方法獲取該物件的Class例項
StreamRule streamRule = new StreamRule();
String s = streamRule.getClass().getName();
System.out.println(s);// 結果:com.fusionskye.ezsonar.model.stream.StreamRule
// 2.使用Class的靜態方法forName(),用類的名字獲取一個Class例項(傳的引數是類的完整路徑名稱)
try {
Class c2 = Class.forName("com.fusionskye.ezsonar.model.stream.StreamRule");
System.out.println(c2.getName());// 結果:com.fusionskye.ezsonar.model.stream.StreamRule
} catch (Exception e) {
e.printStackTrace();
}
// 3.運用.calss的方式獲取Class例項(類)
Class c3 = StreamRule.class;
System.out.println(c3.getName());// 結果:com.fusionskye.ezsonar.model.stream.StreamRule
// 4.運用.calss的方式獲取Class例項(基本型別)
Class c4 = int.class;
System.out.println(c4.getName()); // 結果:int
// 5.運用.calss的方式獲取Class例項(基本資料型別的封裝類)
Class c5 = Integer.TYPE;
System.out.println(c5.getName()); // 結果:int
Class c6 = Integer.class;
System.out.println(c6.getName());// 結果:java.lang.Integer
}
}