❶ java 類載入機制有什麼用
AVA類載入機制詳解
「代碼編譯的結果從本地機器碼轉變為位元組碼,是存儲格式發展的一小步,卻是變成語言發展的一大步」,這句話出自《深入理解JAVA虛擬機》一書,後面關於jvm的系列文章主要都是參考這本書。
JAVA源碼編譯由三個過程組成:
1、源碼編譯機制。
2、類載入機制
3、類執行機制
我們這里主要介紹編譯和類載入這兩種機制。
一、源碼編譯
代碼編譯由JAVA源碼編譯器來完成。主要是將源碼編譯成位元組碼文件(class文件)。位元組碼文件格式主要分為兩部分:常量池和方法位元組碼。
二、類載入
類的生命周期是從被載入到虛擬機內存中開始,到卸載出內存結束。過程共有七個階段,其中到初始化之前的都是屬於類載入的部分
載入----驗證----准備----解析-----初始化----使用-----卸載
系統可能在第一次使用某個類時載入該類,也可能採用預載入機制來載入某個類,當運行某個java程序時,會啟動一個java虛擬機進程,兩次運行的java程序處於兩個不同的JVM進程中,兩個jvm之間並不會共享數據。
1、載入階段
這個流程中的載入是類載入機制中的一個階段,這兩個概念不要混淆,這個階段需要完成的事情有:
1)通過一個類的全限定名來獲取定義此類的二進制位元組流。
2)將這個位元組流所代表的靜態存儲結構轉化為方法區的運行時數據結構。
3)在java堆中生成一個代表這個類的Class對象,作為訪問方法區中這些數據的入口。
由於第一點沒有指明從哪裡獲取以及怎樣獲取類的二進制位元組流,所以這一塊區域留給我開發者很大的發揮空間。這個我在後面的類載入器中在進行介紹。
2、准備階段
這個階段正式為類變數(被static修飾的變數)分配內存並設置類變數初始值,這個內存分配是發生在方法區中。
1、注意這里並沒有對實例變數進行內存分配,實例變數將會在對象實例化時隨著對象一起分配在JAVA堆中。
2、這里設置的初始值,通常是指數據類型的零值。
private static int a = 3;
這個類變數a在准備階段後的值是0,將3賦值給變數a是發生在初始化階段。
3、初始化階段
初始化是類載入機制的最後一步,這個時候才正真開始執行類中定義的JAVA程序代碼。在前面准備階段,類變數已經賦過一次系統要求的初始值,在初始化階段最重要的事情就是對類變數進行初始化,關注的重點是父子類之間各類資源初始化的順序。
java類中對類變數指定初始值有兩種方式:1、聲明類變數時指定初始值;2、使用靜態初始化塊為類變數指定初始值。
初始化的時機
1)創建類實例的時候,分別有:1、使用new關鍵字創建實例;2、通過反射創建實例;3、通過反序列化方式創建實例。
new Test();
Class.forName(「com.mengdd.Test」);
2)調用某個類的類方法(靜態方法)
Test.doSomething();
3)訪問某個類或介面的類變數,或為該類變數賦值。
int b=Test.a;
Test.a=b;
4)初始化某個類的子類。當初始化子類的時候,該子類的所有父類都會被初始化。
5)直接使用java.exe命令來運行某個主類。
除了上面幾種方式會自動初始化一個類,其他訪問類的方式都稱不會觸發類的初始化,稱為被動引用。
1、子類引用父類的靜態變數,不會導致子類初始化。
執行結果:
MIGU
用final修飾某個類變數時,它的值在編譯時就已經確定好放入常量池了,所以在訪問該類變數時,等於直接從常量池中獲取,並沒有初始化該類。
初始化的步驟
1、如果該類還沒有載入和連接,則程序先載入該類並連接。
2、如果該類的直接父類沒有載入,則先初始化其直接父類。
3、如果類中有初始化語句,則系統依次執行這些初始化語句。
在第二個步驟中,如果直接父類又有直接父類,則系統會再次重復這三個步驟來初始化這個父類,依次類推,JVM最先初始化的總是java.lang.Object類。當程序主動使用任何一個類時,系統會保證該類以及所有的父類都會被初始化。
❷ java如何載入一個外部的類或class文件
首先import 類,之後object來裝Class.forName()。inner.現在這object有了import類的所有方法
這forName里的路徑該寫你的類的名字,如果在包里要加包名
❸ JAVA 獲取class對象 類名.class Class.forName()兩種方法什麼情況下使用 為什麼
Class.forName()是根據類名稱來載入類 比如有一個類源名為com.abc.AAA 此處Class.forName(『com.abc.AAA 』).newInstance()就會創建一個AAA對象而.class一般用來獲取類的通用屬性 比如AAA.class.getDeclareMethod()是獲取AAA類的所有聲明的方法 主要用於反射機制
❹ java怎麼根據類名稱得到一個類型
Java 提供了Class類來通過類名獲取對象。
下面請看示例:
先聲明一個Userinfo.java類。
public class Userinfo {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
聲明一個主類。
public class Test {
public static void main(String[] args) throws Exception {
@SuppressWarnings("unchecked")
Class<Userinfo> c = (Class<Userinfo>) Class.forName("Userinfo");
//通過newInstance()獲取對象實例。
Userinfo u = c.newInstance();
try {
System.out.println(Class.forName("Userinfo"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
❺ Java中用import導入類和用Class方法載入類有什麼區別
import僅僅包含導入操作,並不包含將位元組碼文件載入進內存這一動作,將版位元組碼文件載入進內權存是後續的實例化操作完成的。例如通過import導入了一堆包和類,但是後續什麼都沒用(沒用實例化),那麼導入的東西是不會被載入進內存的。而且import是編譯期的,如果你在後續代碼中沒有使用到你導入的內容,那麼import語句甚至不會編譯和執行。查看位元組碼文件可以看出,import的作用就是對你程序中要用到(實例)的東西進行署名(signature),當程序運行的時候好知道你實例化的對象的類的位元組碼文件去哪裡找。
而Class.forName方法包含的動作是:根據給出的全類名(方法的參數)找到對應的位元組碼文件,並將位元組碼文件通過ClassLoader載入進內存中生成Class類對象(方法的返回值就是Class類對象)。
這些就是二者的區別了。
❻ Java 如何顯示 載入類名
程序沒有問題,是你的環境變數沒有設置,特別是CLASSPATH。
具體的環境變數設置方法如下:
1.右擊「我的電腦」,點擊「屬性」:
選擇「高級」選項卡,點擊「環境變數」:
2.在「系統變數」中,設置3項屬性,
JAVA_HOME,PATH,CLASSPATH(不分大小寫)
JAVA_HOME指明JDK安裝路徑,就是剛才安裝時的路徑C:\Program Files\Java\jdk1.5.0_06,此路徑下包括lib,bin,jre等文件夾(此變數最好設置,因為以後運行tomcat,eclipse等都需要依*此變數);
Path使得系統可以在任何路徑下識別java命令,
設為:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
CLASSPATH為java載入類(class or lib)路徑,只有類在classpath中,java命令才能識別,設為:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar (要加.表示當前路徑)
%JAVA_HOME%就是引用前面指定的JAVA_HOME。
3.「開始」->;「運行」,鍵入「cmd」:
4.鍵入命令「java -version」,出現畫面,說明環境變數配置成功.