文章作者:Tyan
博客:noahsnail.com ?|? CSDN ?|? 簡書
1. Class對象
在Java中有兩種對象:Class對象和實例對象,實例對象是類的實例末融,通常是通過new
關(guān)鍵字構(gòu)建的尝胆。Class對象是JVM生成用來保存對象的類的信息的巢块。Java程序執(zhí)行之前需要經(jīng)過編譯礁阁、加載、鏈接和初始化這幾個階段族奢,編譯階段會將源碼文件編譯為.class
字節(jié)碼文件姥闭,編譯器同時會在.class
文件中生成Class對象,加載階段通過JVM內(nèi)部的類加載機制越走,將Class對象加載到內(nèi)存中棚品。在創(chuàng)建對象實例之前,JVM會先檢查Class對象是否在內(nèi)存中存在廊敌,如果不存在铜跑,則加載Class對象,然后再創(chuàng)建對象實例骡澈,如果存在锅纺,則直接根據(jù)Class對象創(chuàng)建對象實例。JVM中只有一個Class對象秧廉,但可以根據(jù)Class對象生成多個對象實例伞广。
2. Class對象的獲得
2.1 類名.class
當(dāng)執(zhí)行類名.class
時拣帽,JVM會先檢查Class對象是否裝入內(nèi)存疼电,如果沒有裝入內(nèi)存,則將Class對象裝入內(nèi)存减拭,然后返回Class對象蔽豺,如果裝入內(nèi)存,則直接返回Class對象拧粪。在加載Class對象后修陡,不會對Class對象進行初始化沧侥。
- Example
public class Test {
static {
System.out.println("Run static initialization block.");
}
{
System.out.println("Run nonstatic initialization block.");
}
}
public class ClassTest {
/**
* @param args
*/
public static void main(String[] args) {
Class t = Test.class;
}
}
- Result
// 空
2.2 Class.forName()
當(dāng)執(zhí)行Class.forName()
時,JVM也會先檢查Class對象是否裝入內(nèi)存魄鸦,如果沒有裝入內(nèi)存宴杀,則將Class對象裝入內(nèi)存,然后返回Class對象拾因,如果裝入內(nèi)存旺罢,則直接返回Class對象。在加載Class對象后绢记,會對類進行初始化扁达,即執(zhí)行類的靜態(tài)代碼塊。forName()
方法中的參數(shù)是類名字符串蠢熄,類名字符串 = 包名 + 類名跪解。Class.forName()
的一個很常見的用法是在加載數(shù)據(jù)庫驅(qū)動的時候。
- Example
package com.tyan.test;
public class Test {
static {
System.out.println("Run static initialization block.");
}
{
System.out.println("Run nonstatic initialization block.");
}
}
package com.tyan.test;
public class ClassTest {
/**
* @param args
*/
public static void main(String[] args) {
try {
Class t = Class.forName("com.tyan.test.Test");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
- Result
Run static initialization block.
2.3 getClass()
getClass()
方法的方法是在通過的類的實例調(diào)用的签孔,即已經(jīng)創(chuàng)建了類的實例叉讥。
- Example
public class Test {
static {
System.out.println("Run static initialization block.");
}
{
System.out.println("Run nonstatic initialization block.");
}
}
public class ClassTest {
public static void main(String[] args) {
Test t = new Test();
Class test = t.getClass();
}
}
- Result
Run static initialization block.
Run nonstatic initialization block.
3. Class類的常用方法
- getName()
一個Class對象描述了一個特定類的屬性,Class類中最常用的方法getName以String的形式返回此Class對象所表示的實體(類骏啰、接口节吮、數(shù)組類、基本類型或void名稱判耕。
- newInstance()
Class還有一個有用的方法可以為類創(chuàng)建一個實例透绩,這個方法叫做newInstance()。例如:x.getClass.newInstance()
壁熄,創(chuàng)建了一個同x
一樣類型的新實例帚豪。newInstance()
方法調(diào)用默認(rèn)構(gòu)造器(無參數(shù)構(gòu)造器)初始化新建對象。
- getClassLoader()
返回該類的類加載器草丧。
- getComponentType()
返回表示數(shù)組組件類型的Class狸臣。
- getSuperclass()
返回表示此 Class 所表示的實體(類、接口昌执、基本類型或 void)的超類的Class烛亦。
- isArray()
判定此 Class 對象是否表示一個數(shù)組類。
4. 反射
JAVA反射機制是在運行狀態(tài)中懂拾,對于任意一個類煤禽,都能夠知道這個類的所有屬性和方法;對于任意一個對象岖赋,都能夠調(diào)用它的任意一個方法和屬性檬果;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。Class對象的獲得是Java反射的基礎(chǔ),Java的反射是另一塊內(nèi)容选脊,本文不涉及杭抠。