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