精彩的人生
好好工作,好好生活
BlogJava
首頁
新隨筆
聯系
聚合
管理
147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(43)
給我留言
查看公開留言
查看私人留言
隨筆分類
BIRT(1)
Eclipse(13)
EMF&GEF(6)
Google Code Jam(3)
Gossip(28)
Java(45)
Job(6)
Social Network(5)
Web(1)
Web Service(41)
我愛吃(2)
隨筆檔案
2008年9月 (1)
2008年8月 (1)
2008年3月 (1)
2008年2月 (1)
2008年1月 (1)
2007年12月 (1)
2007年11月 (2)
2007年10月 (1)
2007年7月 (1)
2007年3月 (1)
2006年10月 (9)
2006年9月 (18)
2006年8月 (4)
2006年7月 (6)
2006年6月 (3)
2006年5月 (11)
2006年4月 (27)
2006年3月 (25)
2006年2月 (6)
2006年1月 (1)
2005年12月 (20)
2005年11月 (6)
相冊
my
收藏夾
GEF/EMF/Eclipse(1)
semantic web(4)
uddi(2)
配色方案(5)
Friends
Reload_cn
uiiang
八進制
老冒的SNS專欄
Web Site
Eclipse Org
Eclipse World
網談
關注虹的新作,關注SNS
搜索
積分與排名
積分 - 444477
排名 - 123
最新評論
1.?re: 當cmd里輸入路徑包含空格的時候
謝謝分享
--網盤搜索-kaopu.so
2.?re: 當cmd里輸入路徑包含空格的時候[未登錄]
我的路徑是中文帶空格怎么辦?
%cd%/bin/bin/java -jar ../../export.jar執行不了啊
--liu
3.?re: Rare Order[未登錄]
@Guest
Wrong at all!!!!
--123
4.?re: 當cmd里輸入路徑包含空格的時候[未登錄]
很有用喲
--temp
5.?re: 插件制作過程記錄(使用TreeViewer貢獻視圖)
代碼下載不了了,
--jiaojiaf
閱讀排行榜
1.?正宗泡椒鳳爪做法(zz)(146687)
2.?當cmd里輸入路徑包含空格的時候(30559)
3.?將String轉換成InputStream(28078)
4.?轉:Eclipse插件FatJar安裝與使用(19256)
5.?簡單的將String類型的xml轉換為對象的代碼(13967)
6.?如何寫好PPT(8830)
7.?讀Axis2用戶幫助文檔(7847)
8.?2005.6.12 使用jsp上傳文件(7565)
9.?從插件/RCP中取得文件路徑的方法(6240)
10.?Eclipse的BPEL(5560)
評論排行榜
1.?正宗泡椒鳳爪做法(zz)(97)
2.?2005.6.12 圖片處理(17)
3.?如何寫好PPT(10)
4.?讀Axis2用戶幫助文檔(9)
5.?gef布局的一點感想(8)
6.?從擴展點中load class(8)
7.?從插件/RCP中取得文件路徑的方法(7)
8.?emf&gef之一example.my.gefpractice(7)
9.?轉:Eclipse插件FatJar安裝與使用(6)
10.?將String轉換成InputStream(6)
初探Java類加載機制的奧秘(zz)
[文章信息]
作者:
cqfz
時間:
2005-02-15
出處:
天極網blog
責任編輯:
方舟
[文章導讀]
在jdk1.2以后,類加載是通過委托來完成的,這意味著如果 ClassLoader 不能找到類……
一、在jdk1.2以后,類加載是通過委托來完成的,這意味著如果 ClassLoader 不能找到類,它會請求父代 ClassLoader 來執行此項任務,所有 ClassLoaders 的根是系統 ClassLoader,它會以缺省方式裝入類 -- 即,從本地文件系統。今天我們就來探討一下在jvm中這些機制是怎樣運行的。讓我們假設有一個class字節碼文件(比如Hello.class文件),那么在應用程序中,他是如何被加載進來,并形成一個類對象的呢?我們這篇文章的目的就是為了解釋這個問題。
在java.lang包里有個ClassLoader類,ClassLoader 的基本目標是對類的請求提供服務。當 JVM 需要使用類時,它根據名稱向 ClassLoader 請求這個類,然后 ClassLoader 試圖返回一個表示這個類的 Class 對象。通過覆蓋對應于這個過程不同階段的方法,可以創建定制的 ClassLoader。其中有個loadClass(String name, boolean resolve)方法,該方法為ClassLoader的入口點,在jdk1.2以后,loadClass方法將缺省調用findClass方法,詳細內容可以參考API文檔,我們編寫的ClassLoader主要就是為了覆蓋以上兩個方法。回到我們剛才的問題,怎樣讀進字節碼文件,并把它構成一個類對象呢?在ClassLoader里有個方法,Class defineClass(String name, byte[] b, int off, int len),答案就在這里了,我們根據把class字節碼文件(如Hello.class)讀進一個字節數組里,byte[] b,并把它轉化為Class對象,而這些數據可以來源于文件,網絡等,神奇吧:)
defineClass管理 JVM 的許多復雜、神秘和倚賴于實現的方面 -- 它把字節碼分析成運行時數據結構、校驗有效性等等。不必擔心,您無需親自編寫它。事實上,即使您想要這么做也不能覆蓋它,因為它已被標記成最終的。
其他一些方法:
findSystemClass方法:從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用 defineClass 將原始字節轉換成 Class 對象,以將該文件轉換成類。
findClass方法:jdk1.2以后loadClass 的缺省實現調用這個新方法。findClass 的用途包含您的 ClassLoader 的所有特殊代碼,而無需要復制其它代碼(例如,當專門的方法失敗時,調用系統 ClassLoader)。
getSystemClassLoader: 如果覆蓋 findClass 或 loadClass,getSystemClassLoader 使您能以實際 ClassLoader 對象來訪問系統 ClassLoader(而不是固定的從 findSystemClass 調用它)。
getParent:為了將類請求委托給父代 ClassLoader,這個新方法允許 ClassLoader 獲取它的父代 ClassLoader。當使用特殊方法,定制的 ClassLoader 不能找到類時,可以使用這種方法。
resolveClass: 可以不完全地(不帶解析)裝入類,也可以完全地(帶解析)裝入類。當編寫我們自己的 loadClass 時,可以調用 resolveClass,這取決于 loadClass 的 resolve 參數的值。
findLoadedClass:充當一個緩存,當請求 loadClass 裝入類時,它調用該方法來查看 ClassLoader 是否已裝入這個類,這樣可以避免重新裝入已存在類所造成的麻煩。應首先調用該方法。
二、工作流程:
1)調用 findLoadedClass(String) 來查看是否存在已裝入的類,如果沒有,那么采用那種特殊的神奇方式來獲取原始字節。
2)通過父類ClassLoader調用loadClass方法,如果父類ClassLoader是null,那么按缺省方式裝入類,即系統ClassLoader。
3)調用findClass(String)去查找類并獲取類;
4)如果loadClass 的 resolve 參數的值為true,那么調用 resolveClass 解析 Class 對象.
5)如果還沒有類,返回 ClassNotFoundException。
6)否則,將類返回給調用程序。
三、一個實現了ClassLoader的例子:
/**?*/
/**
*CompilingClassLoader.java
*Copyright?2005-2-12
*/
import
?java.io.
*
;
public
?
class
?CompilingClassLoader?
extends
?ClassLoader
{
//
讀取一個文件的內容
private
?
byte
[]?getBytes(String?filename)?
throws
?IOException
{
File?file
=
new
?File(filename);
long
?len
=
file.length();
byte
[]?raw
=
new
?
byte
[(
int
)len];
FileInputStream?fin
=
new
?FileInputStream(file);
int
?r
=
fin.read(raw);
if
(r
!=
len)?
throw
?
new
?IOException(
"
Can't?read?all,
"
+
r
+
"
!=
"
+
len);
fin.close();
return
?raw;
}
private
?
boolean
?compile(String?javaFile)?
throws
?IOException
{
System.out.println(
"
CCL:Compiling?
"
+
javaFile
+
"
"
);
//
調用系統的javac命令
Process?p
=
Runtime.getRuntime().exec(
"
javac?
"
+
javaFile);
try
{
//
其他線程都等待這個線程完成
p.waitFor();
}
catch
(InterruptedException?ie)
{
System.out.println(ie);
}
int
?ret
=
p.exitValue();
return
?ret
==
0
;
}
public
?Class?loadClass(String?name,
boolean
?resovle)?
throws
?ClassNotFoundException
{
Class?clas
=
null
;
clas
=
findLoadedClass(name);
//
這里說明了包的表示
String?fileStub
=
name.replace(
'
.
'
,
'
/
'
);
String?javaFilename
=
fileStub
+
"
.java
"
;
String?classFilename
=
fileStub
+
"
.class
"
;
File?javaFile
=
new
?File(javaFilename);
File?classFile
=
new
?File(classFilename);
//
如果存在class文件就不編譯
if
(javaFile.exists()
&&
(
!
classFile.exists()
||
javaFile.lastModified()
>
classFile.lastModified()))
{
try
{
if
(
!
compile(javaFilename)
||!
classFile.exists())
{
throw
?
new
?ClassNotFoundException(
"
ClassNotFoundExcetpion:
"
+
javaFilename);
}
}
catch
(IOException?ie)
{
throw
?
new
?ClassNotFoundException(ie.toString());
}
}
try
{
byte
[]?raw
=
getBytes(classFilename);
//
通過讀入數據來構造一個類結構,這是核心
clas
=
defineClass(name,raw,
0
,raw.length);
}
catch
(IOException?ie)
{
//
}
if
(clas
==
null
)
{
clas
=
findSystemClass(name);
}
System.out.println(
"
findSystemClass:
"
+
clas);
if
(resovle?
&&
?clas
!=
null
)
{
resolveClass(clas);
}
if
(clas
==
null
)
{
throw
?
new
?ClassNotFoundException(name);
}
return
?clas;
}
}
測試該loader:
/**?*/
/**
*TestRun.java
*Copyright?2005-2-11
*/
import
?java.lang.reflect.
*
;
public
?
class
?TestRun
{
public
?
static
?
void
?main(String[]?args)?
throws
?Exception
{
String?progClass
=
args[
0
];
String?progArgs[]
=
new
?String[args.length
-
1
];
System.arraycopy(args,
1
,progArgs,
0
,progArgs.length);
CompilingClassLoader?ccl
=
new
?CompilingClassLoader();
Class?clas
=
ccl.loadClass(progClass);
//
返回一個class的type
Class[]?mainArgType
=
{(
new
?String[
0
]).getClass()}
;
Method?main
=
clas.getMethod(
"
main
"
,mainArgType);
Object?argsArray[]
=
{progArgs}
;
main.invoke(
null
,argsArray);
}
}
以上的核心內容已經編寫完了,編譯后,我們得到兩個文件:
CompilingClassLoader.class,TestRun.class
四、編寫一個例子,然后運行我們的ClassLoader
/**?*/
/**
*Hello.java
*/
public
?
class
?Hello
{
public
?
static
?
void
?main(String[]?args)
{
if
(args.length
!=
1
)
{
System.err.println(
"
Error,exit!
"
);
System.exit(
1
);?
}
String?name
=
args[
0
];
System.out.println(
"
Hello,
"
+
name);
}
}
?
好了,運行java TestRun Hello 阿飛
.
.
.
Hello,阿飛
原文:
http://www.yesky.com/SoftChannel/72342371961929728/20050212/1911003.shtml
posted on 2006-10-23 16:19
hopeshared
閱讀(1877)
評論(0)
編輯
收藏
所屬分類:
Java
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關文章:
一段關于callback的代碼
當cmd里輸入路徑包含空格的時候
java類加載的表現形式(zz)
初探Java類加載機制的奧秘(zz)
Java類加載內幕(zz)
使用Jakarta Commons Pool處理對象池化(zz)
對象池(對象緩沖池)-高手進階(zz)
簡單的將String類型的xml轉換為對象的代碼
一段很好用的判斷數據庫中某張表是否存在的代碼
轉:Java Annotation 高級應用
Powered by:
BlogJava
Copyright © hopeshared
主站蜘蛛池模板:
国产精品亚洲一区二区三区久久
|
亚洲精品午夜无码电影网
|
亚洲人成人无码网www电影首页
|
亚洲熟妇AV一区二区三区宅男
|
久久精品免费观看国产
|
国产亚洲?V无码?V男人的天堂
|
黄色视屏在线免费播放
|
日韩精品视频免费在线观看
|
亚洲精品第一国产综合精品
|
a级毛片免费高清毛片视频
|
又黄又爽的视频免费看
|
亚洲人成人网毛片在线播放
|
18国产精品白浆在线观看免费
|
亚洲日本va午夜中文字幕一区
|
韩国免费A级毛片久久
|
www.亚洲精品
|
国产亚洲精品91
|
国产乱子影视频上线免费观看
|
在线亚洲高清揄拍自拍一品区
|
182tv免费视视频线路一二三
|
亚洲av无码不卡
|
国产精品免费高清在线观看
|
日韩亚洲人成在线综合日本
|
三级毛片在线免费观看
|
亚洲色成人网站WWW永久
|
jizz免费观看视频
|
久久国产成人亚洲精品影院
|
亚洲一区二区电影
|
三年片在线观看免费大全电影
|
国产精品无码免费专区午夜
|
免费的一级黄色片
|
亚洲精品无码久久久久久
|
思思99re66在线精品免费观看
|
欧洲 亚洲 国产图片综合
|
青青草国产免费久久久91
|
久久精品国产亚洲AV电影网
|
四虎影永久在线高清免费
|
日本一区二区在线免费观看
|
久久精品国产亚洲7777
|
巨胸喷奶水视频www免费视频
|
亚洲av日韩av天堂影片精品
|