文章目錄
-
- 概述
- 反射的實作OR擷取Class對象的方式
- 反射API
-
- 擷取類的構造方法的Constructor對象(數組)
- 擷取類成員變量的Field對象(數組)
- 類的方法的Method對象(數組)
- 類的其他資訊
概述
一般在執行個體化對象時,必須要知道類名才可以執行個體化它的對象,這樣我們在應用方面就會受到限制,反射技術,讓我們不知道這個類的類名就可以執行個體化它的對象。
- java程式在運作時可以獲得任何一個類的位元組碼資訊,包括類的修飾符(public,static等),基類(超類,父類),實作的接口,字段和方法等資訊.
- java程式在運作時可以根據位元組碼資訊來建立該類的執行個體對象,改變對象的字段内容和調用對象方法.
這樣的機制就叫反射技術。允許程式在運作過程中取得任何一個已知名稱的類的内部資訊.
将類的各個組成部分封裝為其他對象,
- 可以在程式運作過程中,操作這些對象。
- 可以解耦,提高程式的可擴充性
通過反射機制,我們可以在運作期間擷取對象的類型資訊。利用這一點我們可以實作工廠模式和代理模式等設計模式
反射的實作OR擷取Class對象的方式
-
:将位元組碼檔案加載進記憶體,傳回Class對象Class.forName("全類名")
- 多用于配置檔案,将類名定義在配置檔案中。讀取檔案,加載類
-
:通過類名的屬性class擷取,多用于參數的傳遞類名.class
-
:·對象.getClass()
方法在Object類中定義着。.多用于對象的擷取位元組碼的方式getClass()
- 通過類加載器實作,
getClassLoader()
結論:
同一個位元組碼檔案(*.class)在一次程式運作過程中,隻會被加載一次,不論通過哪一種方式擷取的Class對象都是同一個。
package reflect;
public class JavaClass {
//成員變量
public String name;
public Integer id;
//構造方法
public JavaClass() {}
//成員方法
public void sayHello(){}
public JavaClass(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
public class ClassFor {
@Test
public void testJavaClass() throws ClassNotFoundException {
Class aClass = Class.forName("reflect.JavaClass");
System.out.println("Class.forName:"+aClass);
Class<JavaClass> javaClassClass = JavaClass.class;
System.out.println("className.class:"+javaClassClass);
JavaClass javaClass = new JavaClass();
Class<? extends JavaClass> aClass1 = javaClass.getClass();
System.out.println("Object.getClass:"+aClass1);
Field[] fields = javaClassClass.getFields();
Arrays.stream(fields).forEach(System.out::println);
}
}
運作結果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyYtJ2d1M0T6NGVNlXSU1UejRUT1UERNlHOpNGbSNzYoFjMM5WMXF2aWNjYz5kMM5WNyI2bwNDZsVjMMRXOykVdR5mYsJlbiZnTtNGbOhFZpZFShBDbyoVdjhVW5lTeMZTTINGMShUYvwlbj5yZtlmbkN3YuQnclZnbvN2Ztl2Lc9CX6MHc0RHaiojIsJye.jpg)
反射API
反射API位于java.lang.reflect包中.主要包括以下幾類:
擷取類的構造方法的Constructor對象(數組)
-
類:用來描述一個類的構造方法Constructor
-
類:用來描述一個類的成員變量Field
-
類:用來描述一個類的方法.Method
-
類:用來描述類内各元素的修飾符Modifer
-
:用來對數組進行操作.Array
擷取類成員變量的Field對象(數組)
●
Field[] getDeclaredFields()
:傳回已加載類聲明的所有成員變量的Field對象數組,不包括從父類繼承的成員變量.
●
Field getDeclaredField(String name)
:傳回已加載類聲明的所有成員變量的Field對象,不包括從父類繼承的成員變量,參數name指定成員變量的名稱.
●
Field[] getFields()
:傳回已加載類聲明的所有public型的成員變量的Field對象數組,包括從父類繼承的成員變量
●
Field getField(String name)
:傳回已加載類聲明的所有成員變量的Field對象,包括從父類繼承的成員變量,參數name指定成員變量的名稱.
類的方法的Method對象(數組)
●
Method[] getDeclaredMethods()
:傳回已加載類聲明的所有方法的Method對象數組,不包括從父類繼承的方法.
●
Method getDeclaredMethod(String name,Class[] paramTypes):
傳回已加載類聲明的所有方法的Method對象,不包括從父類繼承的方法,參數name指定方法的名稱,參數paramTypes指定方法的參數類型.
●
Method[] getMethods()
:傳回已加載類聲明的所有方法的Method對象數組,包括從父類繼承的方法.
●
Method getMethod(String name,Class[] paramTypes)
:傳回已加載類聲明的所有方法的Method對象,包括從父類繼承的方法,參數name指定方法的名稱,參數paramTypes指定方法的參數類型
類的其他資訊
●
int getModifiers()
:傳回已加載類的修飾符的整形辨別值.
●
Package getPackage()
:傳回已加載類的包名
●
Class getSuperclass()
:傳回已加載類的父類的Class執行個體.
●
Class [] getInterfaces()
:傳回已加載類實作的接口的Class對象數組.
●
boolean isInterface()
:傳回已加載類是否是接口.