在Java開發(fā)特別是數(shù)據(jù)庫開發(fā)中,經(jīng)常會用到Class.forName( )這個方法。通過查詢Java Documentation我們會發(fā)現(xiàn)使用Class.forName( )靜態(tài)方法的目的是為了動態(tài)加載類。在加載完成后,一般還要調(diào)用Class下的newInstance( )靜態(tài)方法來實(shí)例化對象以便操作。因此,單單使用Class.forName( )是動態(tài)加載類是沒有用的,其最終目的是為了實(shí)例化對象。
?
?? 這里有必要提一下就是Class下的newInstance()和new有什么區(qū)別?,首先,newInstance( )是一個方法,而new是一個關(guān)鍵字,其次,Class下的newInstance()的使用有局限,因?yàn)樗蓪ο笾荒苷{(diào)用無參的構(gòu)造函數(shù),而使用 new關(guān)鍵字生成對象沒有這個限制。
?
?? 好,到此為止,我們總結(jié)如下:
?
?? Class.forName("")返回的是類
?
?? Class.forName("").newInstance()返回的是object
?
?? 有數(shù)據(jù)庫開發(fā)經(jīng)驗(yàn)朋友會發(fā)現(xiàn),為什么在我們加載數(shù)據(jù)庫驅(qū)動包的時候有的卻沒有調(diào)用newInstance( )方法呢?即有的jdbc連接數(shù)據(jù)庫的寫法里是Class.forName(xxx.xx.xx);而有一 些:Class.forName(xxx.xx.xx).newInstance(),為什么會有這兩種寫法呢?
?? 剛才提到,Class.forName("");的作用是要求JVM查找并加載指定的類,如果在類中有靜態(tài)初始化器的話,JVM必然會執(zhí)行該類的靜態(tài)代碼 段。而在JDBC規(guī)范中明確要求這個Driver類必須向DriverManager注冊自己,即任何一個JDBC?Driver的 Driver類的代碼都必須類似如下:
??
1
public
class
MyJDBCDriver
implements
Driver {
2
static
{
3
DriverManager.registerDriver(
new
MyJDBCDriver());
4
}
5
}
?
既然在靜態(tài)初始化器的中已經(jīng)進(jìn)行了注冊,所以我們在使用JDBC時只需要Class.forName(XXX.XXX);就可以了。
?
貼出Proxool 連接池的靜態(tài)初始化方法:
1
public
class
ProxoolDriver
implements
Driver {
2
????
private
static
final
Log LOG = LogFactory.getLog(ProxoolDriver.
class
);
3
????
static
{
4
????????
try
{
5
???????????? DriverManager.registerDriver(
new
ProxoolDriver());
6
???????? }
catch
(SQLException e) {
7
??????????? System.out.println(e.toString());
8
??????? }
9
??? }
10
}
?
1: Class cl=A.class; ?
? ? ? ? ? ? ? ? ? JVM將使用類A的類裝載器, 將類A裝入內(nèi)存(前提是:類A還沒有裝入內(nèi)存),不對類A做類的初始化工作.返回類A的Class的對象。
2:Class cl=對象引用o.getClass();
? ? ? ? ? ? ? ? ? 返回引用o運(yùn)行時真正所指的對象(因?yàn)?子對象的引用可能會賦給父對象的引用變量中)所屬的類的Class的對象 。
3:Class.forName("類名");
? ? ? ? ? ? ? ? ? .裝入類A,并做類的初始化
.getClass()是動態(tài)的,其余是靜態(tài)的。
.class和class.forName()只能返回類內(nèi)field的默認(rèn)值,getClass可以返回當(dāng)前對象中field的最新值
Class.forName() 返回的是一個類,
.newInstance() 后才創(chuàng)建一個對象,
Class.forName()的作用是要求JVM查找并加載指定的類,也就是說JVM會執(zhí)行該類的
1
public
class
Person {
2
????
private
String name = "Alfira"
;
3
????
public
void
getName() {
4
??????? System.out.println(name);
5
??? }
6
????
public
void
setName(String name,
int
a) {
7
????????
this
.name = name +
a;
8
??? }
9
}
?1
import
java.lang.reflect.Method;
2
3
public
class
Test {
4
5
????
/**
6
???? *
@param
args
7
?????
*/
8
????
public
static
void
main(String[] args) {
9
???????? show("yerasel.Person"
);
10
??? }
11
12
????
private
static
void
show(String name) {
13
????????
try
{
14
????????????
//
JVM將使用類A的類裝載器,將類A裝入內(nèi)存(前提是:類A還沒有裝入內(nèi)存),不對類A做類的初始化工作
15
???????????? Class classtype3 = Person.
class
;
16
????????????
//
獲得classtype中的方法
17
???????????? Method getMethod3 = classtype3.getMethod("getName",
new
Class[] {});
18
???????????? Class[] parameterTypes3 = { String.
class
,
int
.
class
};
19
???????????? Method setMethod3 =
classtype3
20
???????????????????? .getMethod("setName"
, parameterTypes3);
21
22
????????????
//
實(shí)例化對象,因?yàn)檫@一句才會輸出“靜態(tài)初始化”以及“初始化”
23
???????????? Object obj3 =
classtype3.newInstance();
24
????????????
//
通過實(shí)例化后的對象調(diào)用方法
25
???????????? getMethod3.invoke(obj3);
//
獲取默認(rèn)值
26
???????????? setMethod3.invoke(obj3, "Setting new ", 3);
//
設(shè)置
27
???????????? getMethod3.invoke(obj3);
//
獲取最新
28
???????????? System.out.println("----------------"
);
29
30
????????????
//
返回運(yùn)行時真正所指的對象
31
???????????? Person p =
new
Person();
32
???????????? Class classtype = p.getClass();
//
Class.forName(name);
33
????????????
//
獲得classtype中的方法
34
???????????? Method getMethod = classtype.getMethod("getName",
new
Class[] {});
35
???????????? Class[] parameterTypes = { String.
class
,
int
.
class
};
36
???????????? Method setMethod = classtype.getMethod("setName"
, parameterTypes);
37
???????????? getMethod.invoke(p);
//
獲取默認(rèn)值
38
???????????? setMethod.invoke(p, "Setting new ", 1);
//
設(shè)置
39
???????????? getMethod.invoke(p);
//
獲取最新
40
???????????? System.out.println("----------------"
);
41
42
????????????
//
裝入類,并做類的初始化
43
???????????? Class classtype2 =
Class.forName(name);
44
????????????
//
獲得classtype中的方法
45
???????????? Method getMethod2 = classtype2.getMethod("getName",
new
Class[] {});
46
???????????? Class[] parameterTypes2 = { String.
class
,
int
.
class
};
47
???????????? Method setMethod2 =
classtype2
48
???????????????????? .getMethod("setName"
, parameterTypes2);
49
????????????
//
實(shí)例化對象
50
???????????? Object obj2 =
classtype2.newInstance();
51
????????????
//
通過實(shí)例化后的對象調(diào)用方法
52
???????????? getMethod2.invoke(obj2);
//
獲取默認(rèn)值
53
???????????? setMethod2.invoke(obj2, "Setting new ", 2);
//
設(shè)置
54
???????????? getMethod2.invoke(obj2);
//
獲取最新
55
56
???????????? System.out.println("----------------"
);
57
58
???????? }
catch
(Exception e) {
59
??????????? System.out.println(e);
60
??????? }
61
??? }
62
}