Java中的類路徑分“編譯后的存放路徑” 和 “運行時的查找路徑”,下面分別談談 1. java編譯后的類存放路徑, 分兩種:“源文件被直接編譯”和“源文件被間接編譯” 1-1源文件直接編譯 什么是源文件直接編譯:即通過javac直接編譯源文件 建立d:\my目錄,在其目錄下新建一個文件,如下: Public class HelloWorld{ Public static void main(String[] args){ System.out.println(“HelloWorld”); } } 在命令行輸入: javac HelloWorld.java 這時在d:\my這個目錄下就產(chǎn)生了一個類文件HelloWorld.class 在命令行輸入: java HelloWorld HelloWorld 正常輸出 改變一: 把原文件中的輸出內容改為”changeHelloWorld” 重新編譯,運行,可以看到在控制臺輸出了 changeHelloWorld 改變二: 恢復一的改變,并刪除之前生成的類文件, 在源文件中的頭部加入 Package com.test; 然后在命令行輸入: javac –d . HelloWorld.java 這時在d:\my這個目錄下就產(chǎn)生了一個新的目錄com\test,類文件HelloWorld.class就位于test下 注,如果不指明路徑,則javac只會把生成的類文件放在默認包中,如同沒包 改變三: 刪除改變二中所產(chǎn)生的目錄結構與類 然后在命令行輸入: javac –d d:\ HelloWorld.java 這時在d:\ 這個根目錄下就產(chǎn)生了一個新的目錄com\test,類文件HelloWorld.class就位于test下 總結:對于源文件被直接編譯的,其規(guī)則如下: 1. 每一次執(zhí)行javac命令都會重新編譯源文件, 2. 編譯后的類文件的存放地址可以指定 3. 源文件帶package結構的,編譯時系統(tǒng)直接產(chǎn)生類文件存放的目錄結構(針對package所指定,注意一定要明確指定編譯后的路徑喔) 1-2源文件間接編譯 什么是源文件間接編譯:放在A類中的B類,當A.java通過javac編譯時,B也會被編譯 建立d:\my1目錄,在其目錄下新建兩個文件,如下: A. java public class A{ public static void main(String[] args){ B b1 = new B(); b1.print(); } } B. java public class B{ public void print(){ System.out.println("package test"); } } 接著在命令行輸入 javac A.java 這時在d:\my1這個目錄下就產(chǎn)生了兩個類文件A.class與B.class 執(zhí)行java A Package test 改變一: 刪除以上所產(chǎn)生的類文件,修改兩個文件的源代碼,分別在頭部加上import edu.nctu.*;和package edu.nctu;即 A. java import edu.nctu.*; public class A{ public static void main(String[] args){ B b1 = new B(); b1.print(); } } B. java package edu.nctu; public class B{ public void print(){ System.out.println("package test"); } } 在命令行輸入: Javac A.java 接著會出現(xiàn)一些錯誤提示,主要提示如下: A. java:1:package edu.nctu does not exist 解決方式:把d:\my1目錄下的B.java移到d:\my1\edu\nctu\下就可以了 注意: 如果d:\my1下仍然存在B.java則還會報錯,因為編譯器總是先到A.java本身所在的路徑中尋找B.java,雖然編譯器找到了B.java,可是對比其package聲明之后,認為它應為位于edu\nctu目錄下,不該在此目錄,因此產(chǎn)生錯誤信息 結論,對于間接被編譯的.java文件,遵從如下規(guī)則 1. 該間接文件沒有包的,則被直接編譯,生成的類文件存放地址和原文件相同 2. 帶包的間接文件,要想正確編譯,必須明確手動建立包目錄結構并且把間接文件置于其內 3. 。。。 2. 運行時的查找路徑 java 是通過 java虛擬機來解釋運行的, 也就是通過 java 命令。 javac 編譯生成的 .class文件就是虛擬機要執(zhí)行的代碼, 稱之為字節(jié)碼(bytecode), 虛擬機通過 classloader來裝載這些字節(jié)碼, 也就是通常意義上的類. 這里就有一個問題, classloader 從哪里知道 java 本身的類庫及用戶自己的類在什么地方呢? 或者有著缺省值(當前路徑). 實際上 java 虛擬機是由 java luncher 初始化的, 也就是 java (或 java.exe)這個程序來做的. 虛擬機按以下順序搜索并裝載所有需要的類: 1, 系統(tǒng)類: 組成 java 平臺的類, 包含 rt.jar等類. 2, 擴展類: 使用 java 擴展機制的類, 都是位于擴展目錄($JAVA_HOME/jre/lib/ext)? 中的 .jar 檔案包. 3, 用戶類: 開發(fā)者定義的類或者沒有使用 java 擴展機制的第三方產(chǎn)品. 以上的類,程序運行時,是如何找到的? 下面做個說明: 當我們在命令行輸入java XXX 的時候,java.exe的工作就是找到合適的JRE來執(zhí)行類文件。Java.exe依照如下邏輯來尋找JRE: 1. 自己的目錄下有沒有JRE目錄 2. 父目錄下的JRE子目錄 3. 查詢windows Registry(HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\). 根據(jù)以上的邏輯,java找到JRE,進而找到系統(tǒng)類和擴展類(因為它們都位于JRE中,且位置固定?),所以“系統(tǒng)類”和“擴展類”的類查找問題就解決了,下面再談談用戶類的查找, 用戶類路徑就是一些包含類文件的目錄, .jar, .zip 文件的列表,我們要使用它,必須在命令行中使用 -classpath 選項或者使用 CLASSPATH 環(huán)境變量來確定這些類的位置或則按缺省查找,規(guī)則如下: * ".", 指當前目錄, 是缺省值. * CLASSPATH 環(huán)境變量, 一旦設置, 將缺省值覆蓋 * 命令行參數(shù) -cp 或者 -classpath, 一旦指定, 將上兩者覆蓋. * 由 -jar 參數(shù)指定的 .jar 檔案包, 就把所有其他的值覆蓋, 所有的類都來自這個指定的檔案包中. 由于生成可執(zhí)行的 .jar 文件, 還需要其他一些知識, 比如 package等,對于package,import機制,下一個專題再嘗試談談. 以上錯漏之處,請大伙提出,先謝過 |
|
來自: 昵稱11323155 > 《我的文章》