已遷往 http://fatmind.iteye.com
題記:.java源文件是如何被找到的?.class字節(jié)碼文件是如何被找到的?內(nèi)容:全部借鑒《Java深度歷險(xiǎn)》
Package:命名空間的問(wèn)題,隔離類之間的關(guān)系。
Import:聲明引入的類的路徑(僅在編譯時(shí)有作用,編譯后的文件,類的聲明已經(jīng)為全路徑);好處“明晰的代碼結(jié)構(gòu),分離在多個(gè)文件;幫助實(shí)現(xiàn)動(dòng)態(tài)鏈接的功能”。
一、編譯
package
edu.nctu;
import
com.taobao.Test;
import
edu.nctu.*;
public
class C
{
public void print() {
System.out.println("package
test") ;
}
}
步驟:
1. 根據(jù)classpath建立,“類相對(duì)路徑參考表”
如:javac –cp .;d:/test/,在d:/下執(zhí)行,結(jié)果:d:/;d:/test/。
2. 以“類相對(duì)路徑參考表”作為相對(duì)起始路徑,驗(yàn)證能夠找到所有要用的package。
根據(jù)import引入的package或全限定類名,import packagename.classname,將packagename之中的“.”以“/”取代.
2.1
若com.taobao.*形式,驗(yàn)證在d:/目錄下是否存在com/taobao/目錄,若不存在,依次檢查d:/test/。
2.2
若com.taobao.Test形式,驗(yàn)證是否存在com/taobao/Test,與上相同。
3. 建立“類參考表”和“相對(duì)類參考表”
3.1
類參考表:com.taobao.Test
3.2
類相對(duì)參考表:com.taobao.*
4. 解析class{} 包含的代碼
是否全限定類名
4.1
是,絕對(duì)路徑 =“類相對(duì)路徑參考表”+全限定類名,查找,不存在為錯(cuò)誤;
4.2
否,絕對(duì)路徑 =“類相對(duì)路徑參考表”,查找;
4.2.1是,編譯
4.2.2否,解析package
4.2.2.1 在類參考表,是否存在1以上的同名類,出錯(cuò);否則,絕對(duì)路徑 =“類相對(duì)路徑參考表”+ “類參考表”,正確。
4.2.2.2 在類參考表找不到,絕對(duì)路徑
= “類相對(duì)路徑參考表”+ “相對(duì)類參考表”,若存在一個(gè)以上的類,出錯(cuò);否則,正確。
提醒:
1.
如果已經(jīng)存在A .class文件,A .java不是必須的;
2.
編譯器在找到源碼或字節(jié)碼,對(duì)會(huì)驗(yàn)證是否屬于此package,但沒(méi)有通過(guò)make機(jī)制的編譯,是不會(huì)驗(yàn)證的;make機(jī)制,即編譯器自動(dòng)維護(hù)具有相互依賴關(guān)系的文件;javac命令直接編譯文件,如:javac -cp d:/test com.edu.C.java,編譯器角度:com.edu.C.java 是一個(gè)文件名,且沒(méi)有通過(guò)make機(jī)制,所以-cp指定的路徑建立的“類相對(duì)路徑參考表”也不會(huì)使用,編譯器直接在當(dāng)前目錄下查找com.edu.C.java,結(jié)果 ClassNotFoundException 。
二、運(yùn)行
1、 編譯結(jié)束后,import指令已經(jīng)不存在,類被替換為“全限定類名”
2、 運(yùn)行時(shí)類的加載,都是通過(guò)classloader進(jìn)行,所以必須遵循正確的“包目錄”結(jié)構(gòu),不管是否直接通過(guò)命令行執(zhí)行。
步驟:
1.
建立“字節(jié)碼路徑參考表”,根據(jù)classpath
2.
絕對(duì)路徑 = “字節(jié)碼路徑參考表”+ 全限定類名,查找;加載;找不到,報(bào)錯(cuò)。