java classpath import package 机制

從一個簡單的例子談談package與import機制



基本原則:為什麼需要將Java文件和類文件切實安置到其所歸屬之Package所對應的相對路徑下。



為什麼要這樣做呢?如果你在程序中,用到打包命令package,並且直接編譯和執行該程序。例如:以下面程序為例:

package a.b.c;

public class hello

{

  public static void main(String args[])

  {    

   System.out.println("Hello the world!");

  }

}

此程序可以編譯通過,但是執行時,卻提示以下錯誤!

david@Wade:~/temp/test_java$javac hello.java


 


david@Wade:~/temp/test_java$java hello

Exception in thread "main" java.lang.NoClassDefFoundError: hello (wrong name: a/

b/c/hello)

        at java.lang.ClassLoader.defineClass0(Native Method)

        at java.lang.ClassLoader.defineClass(ClassLoader.java:537)

        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:12

3)

        at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)

        at java.net.URLClassLoader.access$100(URLClassLoader.java:55)

        at java.net.URLClassLoader$1.run(URLClassLoader.java:194)

        at java.security.AccessController.doPrivileged(Native Method)

        at java.net.URLClassLoader.findClass(URLClassLoader.java:187)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:289)

        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:235)

        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)


 


david@Wade:~/temp/test_java$


 


在test_java目錄下建立一個/a/b/c子目錄把hello.java放在它下面,用以下命令進行編譯和執行時,可正常通過!


 


david@Wade:~/temp/test_java$javac d:/my/test_java/a/b/c/hello.java


 


david@Wade:~/temp/test_java$java a.b.c.hello

Hello the world!


 


david@Wade:~/temp/test_java$


 


再看下面另外一種情況,先讓我們在test_java目錄下建立兩個文件a.java和b.java文件,其內容如下。

a.java文件內容:

import a.b.c.*;

public class a

{

   public static void main(String[] args)

     {

       b b1=new b();

       b1.print();

       }


 


}


 



 



 


b.java文件內容:

package a.b.c;

public class b

{

   public  void print()

     {

      System.out.println("我是被調用子類的程序輸出呀!");

       }

}


 


直接編譯a.java文件時,會提示以下錯誤!


 


david@Wade:~/temp/test_java$javac a.java

a.java:1: package a.b.c does not exist

import a.b.c.*;

^

a.java:6: cannot access b

bad class file: ./b.java

file does not contain class b

Please remove or make sure it appears in the correct subdirectory of the classpa

th.

       b b1=new b();

       ^

2 errors


 


david@Wade:~/temp/test_java$

接下來,我們把b.java移到test_java/a/b/c/下,並把/test_java目錄下的b.java刪除掉呀!重新執行編譯指令,這次肯定可以編譯成功!你可以發現b.java也同時被編譯過了,這就是所謂的make編譯方式。


 


david@Wade:~/temp/test_java$javac a.java


 


david@Wade:~/temp/test_java$


 


提示1:如果你在/test_java目錄下仍保留一個b.java文件的話,執行對主程序的編譯命令時仍會報錯!你自己可以試試呀!

提示2:如果你刪除/test_java/a/b/c/b.java文件的話,保留b.class文件,執行對主程序的編譯命令時是可以通過,此地可以不需要子程序的源代碼。


 


提出一個問題:如果把目錄/a/b/c全部剪切到其它目錄,如D盤根目錄下,在/test_java目錄如果執行編譯和執行命令呢?



很明顯,會報以下錯誤!當然了,前提條件是你沒有設置classpath路徑,其實只要沒把類搜索路徑設置到我這個位置就會出錯的!你試試吧!


 


david@Wade:~/temp/test_java$javac a.java

a.java:1: package a.b.c does not exist

import a.b.c.*;

^

a.java:6: cannot resolve symbol

symbol  : class b

location: class a

       b b1=new b();

       ^

a.java:6: cannot resolve symbol

symbol  : class b

location: class a

       b b1=new b();

                ^

3 errors


 


david@Wade:~/temp/test_java$java a

Exception in thread "main" java.lang.NoClassDefFoundError: a/b/c/b

        at a.main(a.java:6)


 


david@Wade:~/temp/test_java$

解決的辦法可以用以下命令即可正常編譯和執行:


 


david@Wade:~/temp/test_java$javac -classpath  ~/temp/:  a.java


 


david@Wade:~/temp/test_java$java -classpath  ~/temp/: a

我是被調用子類的程序輸出呀!


 


david@Wade:~/temp/test_java$


 


提示3:-classpath參數,缺省是以當前目錄為根基目錄的,即不帶-classpath參數的情況下。

posted @ 2013-04-19 15:03  邓维  阅读(987)  评论(0编辑  收藏  举报