手機技術交流

          funabmol

          2007年11月27日 #

          關于Java包導入的一個奇怪問題(轉貼至 孫鑫)

          這篇文章起源于程序員之家論壇(http://www.sunxin.org)上的一個網友的提問,我對他的問題做了回答。具體網址:http://www.sunxin.org/bbs/dispbbs.asp?boardID=6&ID=12289&page=1

          我感覺這個問題的答案對Java的初學者來說,會有一定的幫助,所以將問題和答案整理成文。

          問題

          首先新建一個目錄存放Java源文件,或者直接在某個盤符下放置程序,例如:D:",然后按照下面的步驟進行實驗(本實驗在D:"目錄下操作)。

          Step1:編寫程序World.java,代碼如下:

          package a;

          public class World

          {

              public World()

              {

              System.out.println(", World!");

              }

          }

          Step2:編寫Hello.java,代碼如下:

          import a.World;

          public class Hello

          {

              public static void main(String[] args)

              {

                  System.out.print("Hello");

                  World world = new World();

              }

          }

          Step3:將兩個程序保存到你所建的目錄下,在這里,我們將它們保存到D:"下。

          Step4:編譯這兩個Java源文件

                 先編譯World.java,執行javac -d . World.java,在D盤生成目錄a,及其中的World.class。接下來編譯Hello.java,執行javac Hello.java,在D盤上生成Hello.class

          Step5:運行Hello

                 執行java Hello,輸出Hello, World!目前一切正常。

          Step6:修改Hello.java

          將第1行的語句“import a.World;”改為“import a.*;”,重新編譯Hello.java,出現下面的錯誤提示:

          錯誤的類文件: ."World.java

          文件不包含類 World

          請刪除該文件或確保該文件位于正確的類路徑子目錄中。

                  World world = new World();

                  ^

          Step7:根據錯誤提示進行下列操作

          按照錯誤提示,刪除 World.java 或者將 World.java 放到其他地方,則程序成功編譯運行。

          問題:

          請問為何會出現Step6中的錯誤呢?使用 import a.*;”導入a下所有類和接口,和使用“import a.World;”導入a包中具體的類,為何會產生上述的差異呢?

          回答

          當你導入一個包中所有的類時,javac在編譯時并不確定你要使用的World類是a包中的類,還是其他包中的類,它會根據你機器上的CLASSPATH環境變量的值去查找類,通常我們在CLASSPATH中會設置一個點(.),表示當前目錄,如果沒有CLASSPATH環境變量,那么在JDK1.4之后,默認也是查找當前目錄。javac在按照文件名(不包括后綴)來查找類,于是找到World.java,而這個文件根本不是字節碼文件,當然就報錯了。當你導入一個具體的類時,javac在分析源文件時就知道了你程序中用的類是a.World,那么它就在CLASSPATH環境變量下查找a目錄下的World類,正好有,于是正確執行。

          為了幫助讀者對這個問題加深理解,我給大家設計了下面的操作步驟(本文是在D盤上操作):

          1)將a目錄剪切到C:"下;
          2)再次執行javac Hello.java,你會看到同樣的錯誤。也就是證實了在出錯之前,javac還沒有去查找a包中的類(對于包是否存在的驗證已經進行)。
          3)執行set classpath=c:"。由于你明確地設置了CLASSPATH環境變量的值,并且沒有包含點(.),因此javac不會再查找當前的目錄。
          4)再次執行javac Hello.java,你會發現成功執行。

          這里面還有一個有趣的現象,如果我們將a目錄下的World.class刪除,替換為World.java,那么在編譯Hello.java時,World也會被自動編譯。

          posted @ 2007-11-27 13:52 smart 閱讀(417) | 評論 (1)編輯 收藏

          My Links

          Blog Stats

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 兴业县| 玉溪市| 黔江区| 庆城县| 仪陇县| 成武县| 靖远县| 新源县| 大石桥市| 吉安县| 兴安县| 丹凤县| 宣化县| 阿鲁科尔沁旗| 辽宁省| 广丰县| 凤庆县| 曲靖市| 白朗县| 苍溪县| 四会市| 合肥市| 延吉市| 彩票| 东兰县| 南阳市| 浦东新区| 呼和浩特市| 句容市| 敦煌市| 通城县| 元氏县| 武威市| 凤台县| 毕节市| 普兰县| 长子县| 东阿县| 苗栗市| 崇明县| 铁力市|