當前位置:首頁 » 編程語言 » 反射java類

反射java類

發布時間: 2023-03-10 14:00:49

『壹』 java裡面反射的原理是什麼

java虛擬機運行時內存有個叫方法區,主要作用是存儲被裝載的類的類型信息。每裝載一個類的時候,java就會創建一個該類的Class對象實例。我們就可以通過這個實例,來訪問這個類的信息。

『貳』 java中反射實例類裝載的步驟及簡要闡述

java反射和類裝載

反射機制:

Person p=new Person();
這是什麼?當然是實例化一個對象了.可是這種實例化對象的方法存在一個問題,那就是必須要知道類名才可以實例化它的對象,這樣我們在應用方面就會受到限制.那麼有沒有這樣一種方式,讓我們不知道這個類的類名就可以實例化它的對象呢?Thank Goodness!幸虧我們用的是java, java就提供了這樣的機制.

1).java程序在運行時可以獲得任何一個類的位元組碼信息,包括類的修飾符(public,static等),基類(超類,父類),實現的介面,欄位和方法等信息.
2).java程序在運行時可以根據位元組碼信息來創建該類的實例對象,改變對象的欄位內容和調用對象方法.
這樣的機制就叫反射技術.可以想像光學中的反射,就像我們照鏡子,鏡子中又出現一個自己(比喻可能不太恰當,但是足以表達清楚意思了).反射技術提供了一種通用的動態連接程序組件的方法,不必要把程序所需要的目標類硬編碼到源程序中,從而使得我們可以創建靈活的程序.

反射的實現步驟( 不問不需要答) ,

1、獲取類的常用方式有三種: a) Class.forName("包名.類名"),最常用、推薦;b) 包名.類名.class 最簡捷;c) 對象.getClass 的方式獲得。

2、對象的實例化,上面已經獲取了類,只需要調用類的實例化方法,類.newInstance()便可。

3、獲取屬性和構造等,可以參考 JavaApi 的調用,類. getDeclaredFields,類. getConstructor(..)等。

Java的反射機制是通過反射API來實現的,它允許程序在運行過程中取得任何一個已知名稱的類的內部信息.反射API位於java.lang.reflect包中.主要包括以下幾類:
1).Constructor類:用來描述一個類的構造方法
2).Field類:用來描述一個類的成員變數
3).Method類:用來描述一個類的方法.
4).Modifer類:用來描述類內各元素的修飾符
5).Array:用來對數組進行操作.
Constructor,Field,Method這三個類都是JVM(虛擬機)在程序運行時創建的,用來表示載入類中相應的成員.這三個類都實現了java.lang.reflect.Member介面,Member介面定義了獲取類成員或構造方法等信息的方法.要使用這些反射API,必須先得到要操作的對象或類的Class類的實例.通過調用Class類的newInstance方法(只能調用類的默認構造方法)可以創建類的實例.這樣有局限性,我們可以先沖類的Class實例獲取類需要的構造方法,然後在利用反射來創建類的一個實例.

類載入機制:



類的載入機制可以分為載入-鏈接-初始化三個階段,鏈接又可以分為驗證、准備、解析三個過程。

載入:通過類的載入器查找並載入二進制位元組流的過程,在堆內存中的方法區生成 一個代表這個類的 java.lang.Class 對象,作為這個類的數據請求入口。(這里可以把上面類載入器載入文件的過程描述一下(參考版本一,不作重復))。

驗證:主要是對一些詞法、語法進行規范性校驗,避免對 JVM 本身安全造成危害; 比如對文件格式,位元組碼驗證,無數據驗證等。但驗證階段是非必須的,可以通過參數 設置來進行關閉,以提高載入的時效。

准備:對類變數分配內存,並且對類變數預初始化,初始化成數據類型的原始值, 比如 static int a=11,會被初始化成成 a=0;如果是 static double a =11,則會被初始化成 a=0.0; 而成員變數只會成實例化後的堆中初始化。

解析:把常量池中的符號引用轉換為直接引用的過程。

初始化:對類的靜態變數和靜態塊中的變數進行初始化。(上面的准備階段可以作為 預初始化,初始到變數類型的原值,但如果被 final 修飾會進行真正初始化)

上面載入、鏈接、初始化的各個階段並不是彼此獨立,而是交叉進行,這點很重要 。

***class.forName和 classloader的區別

Class.forName 和 ClassLoader 都是用來裝載類的,對於類的裝載一般為分三個階段載入、鏈接、編譯,它們裝載類的方式是有區別。

首先看一下 Class.forName(..),forName(..)方法有一個重載方法 forName(className,boolean,ClassLoader),它有三個參數,第一個參數是類的包路徑,第二個參數是 boolean

類型,為 true 地表示 Loading 時會進行初始化,第三個就是指定一個載入器;當你調用class.forName(..)時,默認調用的是有三個參數的重載方法,第二個參數默認傳入 true,第三個參數默認使用的是當前類載入時用的載入器。

ClassLoader.loadClass()也有一個重載方法,從源碼中可以看出它默認調的是它的重載 方法 loadClass(name, false),當第二參數為 false 時,說明類載入時不會被鏈接。這也是兩者之間最大區別,前者在載入的時候已經初始化,後者在載入的時候還沒有鏈接。如果你需要在載入時初始化一些東西,就要用 Class.forName 了,比如我們常用的驅動載入, 實際上它的注冊動作就是在載入時的一個靜態塊中完成的。所以它不能被 ClassLoader 載入代替。

『叄』 JAVA中反射是什麼

JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。

Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。而這也是Java被視為動態語言的一個關鍵性質。

Java反射的功能是在運行時判斷任意一個對象所屬的類,在運行時構造任意一個類的對象,在運行時判斷任意一個類所具有的成員變數和方法,在運行時調用任意一個對象的方法,生成動態代理。

(3)反射java類擴展閱讀:

JAVA中反射實例:

1、Class superClass=clazz.getSuperclass();//獲取父類。

System.out.println("getSuperclass:"+superClass)。

2、Class[] interfaces=clazz.getInterfaces();//獲取實現介面。

System.out.println("getInterfaces:"+interfaces.length)。

3、Constructor[] cons=clazz.getConstructors();//構造方法。

System.out.println("getConstructors:"+cons.length)。

參考資料來源:網路: JAVA反射機制

『肆』 java反射機制的實現原理

反射機制就是java語言在運行時擁有一項自觀的能力。
通過這種能力可以徹底的了解自身的情況為下一步的動作做准備。
下面具體介紹一下java的反射機制。這里你將顛覆原來對java的理解。
Java的反射機制的實現要藉助於4個類:class,Constructor,Field,Method;
其中class代表的時類對象,
Constructor-類的構造器對象,
Field-類的屬性對象,
Method-類的方法對象。
通過這四個對象我們可以粗略的看到一個類的各個組成部分。
Class:程序運行時,java運行時系統會對所有的對象進行運行時類型的處理。
這項信息記錄了每個對象所屬的類,虛擬機通常使用運行時類型信息選擇正 確的方法來執行(摘自:白皮書)。
但是這些信息我們怎麼得到啊,就要藉助於class類對象了啊。
在Object類中定義了getClass()方法。我 們可以通過這個方法獲得指定對象的類對象。然後我們通過分析這個對象就可以得到我們要的信息了。
比如:ArrayList arrayList;
Class clazz = arrayList.getClass();
然後我來處理這個對象clazz。
當然了Class類具有很多的方法,這里重點將和Constructor,Field,Method類有關系的方法。
Reflection 是 Java 程序開發語言的特徵之一,它允許運行中的 Java 程序對自身進行檢查,或者說「自審」,並能直接操作程序的內部屬性。Java 的這一能力在實際應用中也許用得不是很多,但是個人認為要想對java有個更加深入的了解還是應該掌握的。
reflection的工作機制
考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
//forName("java.lang.String")獲取指定的類的對象
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
按如下語句執行:
java DumpMethods java.util.ArrayList
這個程序使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。
Java類反射中的主要方法
對於以下三類組件中的任何一類來說
-- 構造函數、欄位和方法
-- java.lang.Class 提供四種獨立的反射調用,以不同的方式來獲得信息。調用都遵循一種標准格式。以下是用於查找構造函數的一組反射調用:
Constructor getConstructor(Class[] params) -- 獲得使用特殊的參數類型的公共構造函數,
Constructor[] getConstructors() -- 獲得類的所有公共構造函數
Constructor getDeclaredConstructor(Class[] params) -- 獲得使用特定參數類型的構造函數(與接入級別無關)
Constructor[] getDeclaredConstructors() -- 獲得類的所有構造函數(與接入級別無關)
獲得欄位信息的Class 反射調用不同於那些用於接入構造函數的調用,在參數類型數組中使用了欄位名:
Field getField(String name) -- 獲得命名的公共欄位
Field[] getFields() -- 獲得類的所有公共欄位
Field getDeclaredField(String name) -- 獲得類聲明的命名的欄位
Field[] getDeclaredFields() -- 獲得類聲明的所有欄位
用於獲得方法信息函數:
Method getMethod(String name, Class[] params) -- 使用特定的參數類型,獲得命名的公共方法
Method[] getMethods() -- 獲得類的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特寫的參數類型,獲得類聲明的命名的方法
Method[] getDeclaredMethods() -- 獲得類聲明的所有方法
使用 Reflection:
用於 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時候必須要遵循三個步驟:
第一步是獲得你想操作的類的 java.lang.Class 對象。
在運行中的 Java 程序中,用 java.lang.Class 類來描述類和介面等。
下面就是獲得一個 Class 對象的方法之一:
Class c = Class.forName("java.lang.String");
這條語句得到一個 String 類的類對象。還有另一種方法,如下面的語句:
Class c = int.class;
或者
Class c = Integer.TYPE;
它們可獲得基本類型的類信息。其中後一種方法中訪問的是基本類型的封裝類 (如 Intege ) 中預先定義好的 TYPE 欄位。
第二步是調用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。
一旦取得這個信息,就可以進行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它將以文本方式列印出 String 中定義的第一個方法的原型。
處理對象:
a.創建一個Class對象
b.通過getField 創建一個Field對象
c.調用Field.getXXX(Object)方法(XXX是Int,Float等,如果是對象就省略;Object是指實例).
例如:
import java.lang.reflect.*;
import java.awt.*;
class SampleGet {
public static void main(String[] args) throws Exception {
Rectangle r = new Rectangle(100, 325);
printHeight(r);
printWidth( r);
}
static void printHeight(Rectangle r)throws Exception {
//Field屬性名
Field heightField;
//Integer屬性值
Integer heightValue;
//創建一個Class對象
Class c = r.getClass();
//.通過getField 創建一個Field對象
heightField = c.getField("height");
//調用Field.getXXX(Object)方法(XXX是Int,Float等,如果是對象就省略;Object是指實例).
heightValue = (Integer) heightField.get(r);
System.out.println("Height: " + heightValue.toString());
}
static void printWidth(Rectangle r) throws Exception{
Field widthField;
Integer widthValue;
Class c = r.getClass();

widthField = c.getField("width");
widthValue = (Integer) widthField.get(r);
System.out.println("Height: " + widthValue.toString());

}
}

熱點內容
md5加密演算法代碼 發布:2024-11-06 21:31:01 瀏覽:162
tpshop商城源碼 發布:2024-11-06 21:30:45 瀏覽:843
單本小說網站源碼 發布:2024-11-06 21:11:17 瀏覽:546
mtp緩存 發布:2024-11-06 21:06:43 瀏覽:21
P40存儲卡 發布:2024-11-06 21:02:15 瀏覽:921
大容量鐵電存儲器 發布:2024-11-06 21:02:12 瀏覽:451
淘寶課腳本 發布:2024-11-06 21:00:41 瀏覽:688
網路機櫃和伺服器櫃有什麼不同 發布:2024-11-06 20:50:11 瀏覽:965
戰地5如何查看所有伺服器 發布:2024-11-06 20:46:42 瀏覽:654
sql返回執行結果 發布:2024-11-06 20:30:55 瀏覽:961