目錄
- 1 class對象詳解
- 2 Class.forName和ClassLoader.loadClass差別
- 2.1 jvm加載class步驟
- 2.2 兩種方式的詳細方法
- 2.3 兩種方式的差別
- 2.4 舉例說明他們各自的使用方法
java
中把生成
Class
對象和執行個體對象弄混了,更何況生成
Class
對象和生成
instance
都有多種方式。是以隻有弄清其中的原理,才可以深入了解。首先要生成
Class
對象,然後再生成
Instance
。那
Class
對象的生成方式有哪些呢,以及其中是如何秘密生成的呢?
Class
對象的生成方式如下:
-
(注意:類名字元串必須是全稱,包名+類名)Class.forName("類名字元串")
-
類名.class
-
執行個體對象.getClass()
通過一段小程式,來觀察一下
Class
對象的生成的原理。
/**
* 2012-2-6
* Administrator
*/
/**
* @author: 梁煥月
* 檔案名:TestClass.java
* 時間:2012-2-6上午10:01:52
*/
public class TestClass {
public static void main(String[] args) {
try {
//測試Class.forName()
Class testTypeForName=Class.forName("TestClassType");
System.out.println("testForName---"+testTypeForName);
//測試類名.class
Class testTypeClass=TestClassType.class;
System.out.println("testTypeClass---"+testTypeClass);
//測試Object.getClass()
TestClassType testGetClass= new TestClassType();
System.out.println("testGetClass---"+testGetClass.getClass());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TestClassType{
//構造函數
public TestClassType(){
System.out.println("----構造函數---");
}
//靜态的參數初始化
static{
System.out.println("---靜态的參數初始化---");
}
//非靜态的參數初始化
{
System.out.println("----非靜态的參數初始化---");
}
}
測試的結果如下:
---靜态的參數初始化---
testForName---class TestClassType
testTypeClass---class TestClassType
----非靜态的參數初始化---
----構造函數---
testGetClass---class TestClassType
根據結果可以發現,三種生成的
Class
對象一樣的。并且三種生成
Class
對象隻列印一次
靜态的參數初始化
。
我們知道,靜态的方法屬性初始化,是在加載類的時候初始化。而非靜态方法屬性初始化,是
new類
執行個體對象的時候加載。
是以,這段程式說明,三種方式生成
Class對象
,其實隻有一個
Class
對象。在生成
Class
對象的時候,首先判斷記憶體中是否已經加載。
是以,生成
Class
對象的過程其實是如此的:當我們編寫一個新的
java類
時,
JVM
就會幫我們編譯成
class對象
,存放在同名的
.class檔案
中。在運作時,當需要生成這個類的對象,
JVM
就會檢查此類是否已經裝載記憶體中。若是沒有裝載,則把
.class檔案
裝入到記憶體中。若是裝載,則根據
class檔案
生成執行個體對象。
Java
中
class
是如何加載到
JVM
中的:
class
加載到
JVM
中有三個步驟:
-
:(loading)找到class對應的位元組碼檔案。裝載
-
:(linking)将對應的位元組碼檔案讀入到JVM中。連接配接
-
:(initializing)對class做相應的初始化動作。初始化
Java
中兩種加載
class
到
JVM
中的方式
-
其實這種方法調運的是:Class.forName("className");
Class.forName(className, true,ClassLoader.getCallerClassLoader())
方法
參數一:
className
,需要加載的類的名稱。
參數二:true,是否對class進行初始化(需要initialize)
參數三:classLoader,對應的類加載器
-
ClassLoader.laodClass("className");
ClassLoader.loadClass(name, false)
參數一:name,需要加載的類的名稱
參數二:false,這個類加載以後是否需要去連接配接(不需要linking)
forName("")
得到的
class
是已經初始化完成的
loadClass("")
class
是還沒有連接配接的
一般情況下,這兩個方法效果一樣,都能裝載
Class
但如果程式依賴于
Class
是否被初始化,就必須用
Class.forName(name)
了。
Class.forName("com.mysql.jdbc.Driver");//通過這種方式将驅動注冊到驅動管理器上
Connection conn = DriverManager.getConnection("url","userName","password");//通過驅動管理器獲得相應的連接配接
public class Driver extends NonRegisteringDriver
implements java.sql.Driver
{
//注意,這裡有一個static的代碼塊,這個代碼塊将會在class初始化的時候執行
static
{
try
{
//将這個驅動Driver注冊到驅動管理器上
DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}