友快網

導航選單

【高階入門】c語言中的類載入,你知道是什麼意思?-八維教育

今日分享開始啦,請大家多多指教~

這篇文章給大家先簡簡單單地說下類的載入,以及具體實現,可以自己操作一下哦!

類的載入

在程式執行後,首次使用某個類,會把這個類的位元組碼檔案讀取到記憶體,並且會將這個類的所有資訊存到一個Class物件中。

簡單步驟:

1:jvm執行程式碼,例如讀到 new Student()

2 : 讀取Student的位元組碼檔案

3:把位元組碼檔案的內容(讀取成位元組碼物件)儲存到方法區(以前的說法),1。8以後叫做元空間(貌似)

4:最後類載入完成以後,在堆空間建立記憶體空間。

類的載入時機(下面六種)

建立類的例項。(new 一個類)

類的靜態變數,或者為靜態變數賦值。

類的靜態方法。

使用反射方式來強制建立某個類或介面對應的java。lang。Class物件。

初始化某個類的子類。

直接使用java。exe命令來執行某個主類。(編譯 javac 類名。java, 執行 java。類名)

今天的反射也屬於類載入時機的一種

先上程式碼:

類載入時機程式碼演示

1。 建立類的例項。 靜態程式碼塊隨著類的載入而載入,並且只執行一次。

2。 類的靜態變數,或者為靜態變數賦值。

3。 類的靜態方法。

4。反射透過 Class。forName(“全類名”) 進行反射

5。透過子類例項

執行結果

都證明了這個stu類被載入了。

類載入器(暫時先了解了解)

下面說說類載入器,類載入器是負責將實際空間中的某個class檔案讀取到記憶體中並且生成Class的物件。

Java中有三種類載入器,它們分別用於載入不同種類的class:

Java中有三種類載入器,它們分別用於載入不同種類的class:

啟動類載入器(Bootstrap ClassLoader):用於載入系統類庫\bin目錄下的class,例如:rt。jar。

擴充套件類載入器(Extension ClassLoader):用於載入擴充套件類庫\lib\ext目錄下的class。

應用程式類載入器(Application ClassLoader):用於載入我們自定義類的載入器。

進去程式碼看看,我們是如何獲得類載入器的

再點進getClassLoader()方法看看jdk是怎麼描述的

圖中看到,一些實現可能使用null來表示引導類載入器,可能在此類中的實現返回null。

舉個例子。

好了,接下來該回到反射的主題

反射的概念

它一種機制,利用這個機制就可以在程式中對類進行解析,並且可以操作類中所有成員(變數,方法,構造方法)。

使用反射需要一個前提,獲取需要反射的那個類的位元組碼物件。

Class物件的獲取方式

透過類名。class獲得

透過物件名。getClass()方法獲得

透過Class類的靜態方法獲得: static Class forName(“類全名”)

Tips:每個類的Class物件都只有一個

Class類常用的方法

String getSimpleName(); 獲取類名字串

String getName(); 獲取全類名字串

建立類的物件

1.T newInstance(): 建立Class物件關聯類的物件。

2.透過Constructor類來建立物件

首先要獲取構造器類

Class類中與Constructor相關的方法

1。Constructor getConstructor(Class… parameterTypes)

* 根據引數型別獲得對應的Constructor物件。

getConstructor()的原始碼描述

上個使用的程式碼

Java

/**

* 先用getConstructor() 獲取Constructor類物件

* 再透過這個物件例項T。 沒有引數的用法

* @throws Exception

*/

@Test

public void getPublicConstructorWithoutParameter() throws Exception {

Class studentClass = Student。class;

//先獲取無參構造類物件。

Constructor constructor=studentClass。getConstructor();

//再透過這個例項方法,例項這個類

Student student = constructor。newInstance();

}

/**

* 先用getConstructor() 獲取Constructor類物件

* 再透過這個物件例項T。 有引數的用法

* @throws Exception

*/

@Test

public void getPublicConstructor() throws Exception {

Class studentClass = Student。class;

//獲取有參構造類

Constructor constructor=studentClass。getConstructor(int。class);

//輸入引數例項化Student類

Student student = constructor。newInstance(1);

}

如圖所述,如果傳入了沒有相關引數過載的構造器,會報NoSuchMethodException異常

2。Constructor getDeclaredConstructor(Class… parameterTypes)

* 根據引數型別獲得對應的Constructor物件

* 可以是public、protected、(預設)、private修飾符的構造方法。

* 如果是被protected、(預設)、private修飾符修飾的構造器,需要確定本身能否訪問到,如果不能訪問到就要設定許可權,用setAccessible(true)。

暴力獲取構造器,能獲取包括public protected default private

透過getDeclaredConstructor()暴力獲取Student類中除了public其他修飾符的構造器,但這個構造類物件需要設定許可權,setAccessible(true)

具體要不要設定,得看這個修飾符本身能否訪問到相關資源。

圖上是個反例。

3。Constructor[] getConstructors()

獲得類中的所有構造方法物件,只能獲得public的

上程式碼:

透過getConstructors()獲取所有public修飾的構造器類物件。

@Test

public void getAllPublicConstructor(){

Class studentClass = Student。class;

Constructor[] constructors = (Constructor[]) studentClass。getConstructors();

for (Constructor constructor : constructors) {

System。out。println(constructor);

}

}

遍歷列印的結果:

4。Constructor[] getDeclaredConstructors()

獲得類中的所有構造方法物件

可以是public、protected、(預設)、private修飾符的構造方法。

透過getDeclaredConstructors()獲取所有p修飾的構造器類物件。

@Test

public void getAllAccessConstructor(){

Class studentClass = Student。class;

Constructor[] constructors = (Constructor[]) studentClass。getDeclaredConstructors();

for (Constructor constructor : constructors) {

System。out。println(constructor);

}

}

遍歷列印的結果:

獲取成員方法

接下來的部分就不放程式碼演示了,就提供下api。

1 **Method getMethod(String name,Class。。。args);**

方法名和引數型別獲得對應的成員方法物件,只能獲得public的

2 **Method getDeclaredMethod(String name,Class。。。args);**

根據方法名和引數型別獲得對應的成員方法物件,包括public、protected、(預設)、private的

3 **Method[] getMethods();**

獲得類中的所有成員方法物件,返回陣列,只能獲得public修飾的且包含父類的

4**Method[] getDeclaredMethods();**

獲得類中的所有成員方法物件,返回陣列,只獲得本類的,包括public、protected、(預設)、private的

透過反射訪問成員變數

Method物件常用方法

Object invoke(Object obj, Object。。。 args)

* 呼叫指定物件obj的該方法

* args:呼叫方法時傳遞的引數

void setAccessible(true)

設定“暴力訪問”——是否取消許可權檢查,true取消許可權檢查,false表示不取消

透過反射獲取類的成員變數

Class類中與Field相關的方法

Field getField(String name);

* 根據成員變數名獲得對應Field物件,只能獲得public修飾

Field getDeclaredField(String name);

* 根據成員變數名獲得對應Field物件,包括public、protected、(預設)、private的

Field[] getFields();

* 獲得所有的成員變數對應的Field物件,只能獲得public的

Field[] getDeclaredFields();

* 獲得所有的成員變數對應的Field物件,包括public、protected、(預設)、private的

透過反射訪問成員變數

Field物件常用方法

**void  set(Object obj, Object value)**

**void setInt(Object obj, int i)**

**void setLong(Object obj, long l)**

**void setBoolean(Object obj, boolean z)**

**void setDouble(Object obj, double d)**

**Object get(Object obj)

intgetInt(Object obj)**

**long getLong(Object obj)**

**boolean getBoolean(Object ob)**

**double getDouble(Object obj)**

**void setAccessible(true);暴力反射,設定為可以直接訪問私有型別的屬性。**

**Class getType(); 獲取屬性的型別,返回Class物件。**

今日份分享已結束,請大家多多包涵和指點!

上一篇:以太坊價格飆升的背後:區塊鏈技術將使其區塊鏈與其他市場分道揚鑣
下一篇:三星手機在國內佔有率一直在1% 左右,但它為何能在國外賣那麼好?