日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java classpath import package 机制 @Java的ClassPath, Package和Jar

發(fā)布時(shí)間:2024/1/17 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java classpath import package 机制 @Java的ClassPath, Package和Jar 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java classpath import package 機(jī)制

從一個(gè)簡單的例子談?wù)刾ackage與import機(jī)制



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



為什麼要這樣做呢?如果你在程序中,用到打包命令package,並且直接編譯和執(zhí)行該程序。例如:以下面程序?yàn)槔?#xff1a;

package a.b.c;

public class hello

{

? public static void main(String args[])

? {????

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

? }

}

此程序可以編譯通過,但是執(zhí)行時(shí),卻提示以下錯(cuò)誤!

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目錄下建立一個(gè)/a/b/c子目錄把hello.java放在它下面,用以下命令進(jìn)行編譯和執(zhí)行時(shí),可正常通過!


?


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目錄下建立兩個(gè)文件a.java和b.java文件,其內(nèi)容如下。

a.java文件內(nèi)容:

import a.b.c.*;

public class a

{

?? public static void main(String[] args)

???? {

?????? b b1=new b();

?????? b1.print();

?????? }


?


}


?



?



?


b.java文件內(nèi)容:

package a.b.c;

public class b

{

?? public? void print()

???? {

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

?????? }

}


?


直接編譯a.java文件時(shí),會(huì)提示以下錯(cuò)誤!


?


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刪除掉呀!重新執(zhí)行編譯指令,這次肯定可以編譯成功!你可以發(fā)現(xiàn)b.java也同時(shí)被編譯過了,這就是所謂的make編譯方式。


?


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


?


david@Wade:~/temp/test_java$


?


提示1:如果你在/test_java目錄下仍保留一個(gè)b.java文件的話,執(zhí)行對主程序的編譯命令時(shí)仍會(huì)報(bào)錯(cuò)!你自己可以試試呀!

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


?


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



很明顯,會(huì)報(bào)以下錯(cuò)誤!當(dāng)然了,前提條件是你沒有設(shè)置classpath路徑,其實(shí)只要沒把類搜索路徑設(shè)置到我這個(gè)位置就會(huì)出錯(cuò)的!你試試吧!


?


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$

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


?


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


?


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

我是被調(diào)用子類的程序輸出呀!


?


david@Wade:~/temp/test_java$

?

?

? ? ? ? ?Java的ClassPath, Package和Jar(zz)

標(biāo)簽: javajarjdkclassloader數(shù)據(jù)庫驅(qū)動(dòng)程序擴(kuò)展 分類: JAVA(14)

轉(zhuǎn)自:http://hi.baidu.com/sunshibing/blog/item/f7b4994595a9ab3f879473bc.html

前言:


????由于這兩個(gè)問題新手問得較多,?且回答比較零散,?很難統(tǒng)一整理,?所
以就直接寫了一篇,?還請大家見諒.


正文:

一,?類路徑?(class?path)

????當(dāng)你滿懷著希望安裝好了?java,?然后興沖沖地寫了個(gè)?hello?world,然后編譯,?
運(yùn)行,?就等著那兩個(gè)美好的單詞出現(xiàn)在眼前,?可是不幸的是,?只看到了?Can't?find?
class?HelloWorld?或者?Exception?in?thread?"main"?java.lang.NoSuchMethodError:?main.?
為什么呢??編譯好的?class?明明在呀.?
????我們一起來看一看?java?程序的運(yùn)行過程.?我們已經(jīng)知道?java?是通過?java
虛擬機(jī)來解釋運(yùn)行的,?也就是通過?java?命令,?javac?編譯生成的?.class
文件就是虛擬機(jī)要執(zhí)行的代碼,?稱之為字節(jié)碼(bytecode),?虛擬機(jī)通過?classloader
來裝載這些字節(jié)碼,?也就是通常意義上的類.?這里就有一個(gè)問題,?classloader?從
哪里知道?java?本身的類庫及用戶自己的類在什么地方呢??或者有著缺省值(當(dāng)前路徑).
或者要有一個(gè)用戶指定的變量來表明,?這個(gè)變量就是類路徑(classpath),?或者在運(yùn)行
的時(shí)候傳參數(shù)給虛擬機(jī).?這也就是指明?classpath?的三個(gè)方法.?編譯的過程和運(yùn)行
的過程大同小異,?只是一個(gè)是找出來編譯,?另一個(gè)是找出來裝載.?
????實(shí)際上?java?虛擬機(jī)是由?java?luncher?初始化的,?也就是?java?(或?java.exe)?
這個(gè)程序來做的.?虛擬機(jī)按以下順序搜索并裝載所有需要的類:
????1,?引導(dǎo)類:?組成?java?平臺(tái)的類,?包含?rt.jar?和?i18n.jar?中的類.
????2,?擴(kuò)展類:?使用?java?擴(kuò)展機(jī)制的類,?都是位于擴(kuò)展目錄($JAVA_HOME/jre/lib/ext)
中的?.jar?檔案包.
????3,?用戶類:?開發(fā)者定義的類或者沒有使用?java?擴(kuò)展機(jī)制的第三方產(chǎn)品.?你必須在
命令行中使用?-classpath?選項(xiàng)或者使用?CLASSPATH?環(huán)境變量來確定這些類的位置.?我
們在上面所說的用戶自己的類就是特指這些類.
????這樣,?一般來說,?用戶只需指定用戶類的位置,?引導(dǎo)類和擴(kuò)展類是"自動(dòng)"尋找的.
????那么到底該怎么做呢??用戶類路徑就是一些包含類文件的目錄,?.jar,?.zip?文件的
列表,?至于類具體怎么找,?因?yàn)闋砍兜?package?的問題,?下面將會(huì)說到,?暫時(shí)可認(rèn)為
只要包含了這個(gè)類就算找到了這個(gè)類.?根據(jù)平臺(tái)的不同分隔符略有不同,?類?unix?的系
統(tǒng)基本上都是?":",?windows?多是?";".?其可能的來源是:

????*?".",?即當(dāng)前目錄,?這個(gè)是缺省值.
????*?CLASSPATH?環(huán)境變量,?一旦設(shè)置,?將缺省值覆蓋.
????*?命令行參數(shù)?-cp?或者?-classpath,?一旦指定,?將上兩者覆蓋.
????*?由?-jar?參數(shù)指定的?.jar?檔案包,?就把所有其他的值覆蓋,?所有的類都來自這個(gè)指
定的檔案包中.?由于生成可執(zhí)行的?.jar?文件,?還需要其他一些知識(shí),?比如?package,?還有
特定的配置文件,?本文的最后會(huì)提到.?可先看看?jdk?自帶的一些例子.

????我們舉個(gè)?HelloWorld?的例子來說明.?先做以下假設(shè):?
????*?當(dāng)前目錄是?/HelloWorld?(或?c:\HelloWorld,?以后都使用前一個(gè))
????*?jdk?版本為?1.2.2?(linux?下的)
????*?PATH?環(huán)境變量設(shè)置正確.?(這樣可以在任何目錄下都可以使用工具)
????*?文件是?HelloWorld.java,?內(nèi)容是:

????public?class?HelloWorld
????{
????????public?static?void?main(String[]?args)
????????{
????????????System.out.println("Hello?World!\n");
????????????System.exit(0);
????????}
????}

????首先這個(gè)文件一定要寫對,?如果對?c?熟悉的話,?很有可能寫成這樣:

????public?static?void?main(int?argc,?String[]?argv)
????{
????????....
????}

????這樣是不對的,?不信可以試一試.?由于手頭沒有?java?的規(guī)范,?所以
作如下猜想:?java?的?application?程序,?必須以?public?static?void?main(String[])
開始,?其他不一樣的都不行.

????到現(xiàn)在為止,?我們設(shè)置方面只設(shè)置了?PATH.

????1,?當(dāng)前路徑就是指你的?.class?文件在當(dāng)前目錄下,?

???????[HelloWorld]$?javac?HelloWorld.java??//這一步不會(huì)有多大問題,
???????[HelloWorld]$?java?HelloWorld????????//?這一步可能就會(huì)有問題.

????如果出了象開頭那樣的問題,?首先確定不是由于敲錯(cuò)命令而出錯(cuò).?如果沒有敲錯(cuò)命令,
那么接著做:

???????[HelloWorld]$?echo?$CLASSPATH???
???????或者
???????c:\HelloWorld>echo?%CLASSPATH%

????看看?CLASSPATH?環(huán)境變量是否設(shè)置了,?如果設(shè)置了,?那么用以下命令:

???????[HelloWorld]$?CLASSPATH=?
???????或者
???????c:\HelloWorld>?set?CLASSPATH=

????來使它為空,?然后重新運(yùn)行.?這次用戶類路徑缺省的是?".",?所以應(yīng)該不會(huì)有相
同的問題了.?還有一個(gè)方法就是把?"."?加入到?CLASSPATH?中.

???????[/]$?CLASSPATH=$CLASSPATH:.
???????或者
???????c:\HelloWorld>?set?CLASSPATH=%CLASSPATH%;.

????同樣也可以成功.?Good?Luck.

????2,?當(dāng)你的程序需要第三方的類庫支持,?而且比較常用,?就可以采用此種方法.比如常
用的數(shù)據(jù)庫驅(qū)動(dòng)程序,?寫?servlet?需要的?servlet?包等等.?設(shè)置方法就是在環(huán)境變量中
加入?CLASSPATH.?然后就可以直接編譯運(yùn)行了.?還是以?HelloWorld?為例,?比如你想在根
目錄中運(yùn)行它,?那么你直接在根目錄下執(zhí)行?
??????
??????$?java?HelloWorld
??????或者
??????c:\>java?HelloWorld
???????
????這樣肯定會(huì)出錯(cuò),?如果你的?CLASSPATH?沒有改動(dòng)的話.?我想大家應(yīng)該知道為什么錯(cuò)了
吧,?那么怎么改呢??前面說過,?用戶類路徑就是一些包含你所需要的類的目錄,?.jar?檔案
包,?.zip?包.?現(xiàn)在沒有生成包,?所以只好把?HelloWorld.class?所在的目錄加到?CLASSPATH
了,?根據(jù)前面的做法,?再運(yùn)行一次,?看看,?呵呵,?成功了,?換個(gè)路徑,?又成功了!!?不僅僅可
以直接運(yùn)行其中的類,?當(dāng)你要?import?其中的某些類時(shí),?同樣處理.
????不知道你想到?jīng)]有,?隨著你的系統(tǒng)的不斷的擴(kuò)充,?(當(dāng)然了,?都是一些需要?java?的東西)
如果都加到這個(gè)環(huán)境變量里,?那這個(gè)變量會(huì)越來越臃腫,?雖然環(huán)境變量空間可以開很大,?總
覺得有些不舒服.?看看下面一個(gè)方法.
????
????3,?在命令行參數(shù)中指明?classpath.

????還是和上面相同的目標(biāo),?在任何目錄下執(zhí)行?HelloWorld,?用這個(gè)方法怎么實(shí)現(xiàn)呢?

??????[/]$?java?-cp?/HelloWorld?HelloWorld
??????或者
??????c:\>java?-cp?c:\HelloWorld?HelloWorld

????就可以了.?這是這種方法的最簡單的應(yīng)用了.?當(dāng)你使用了另外的包的時(shí)候,?還可以采用這
種方法.?例如:

??????$?javac?-classpath?aPath/aPackage.jar:.?myJava.java
??????$?java??-cp?aPath/aPackage.jar:.?myJava
??????或者
??????c:\>?javac?-classpath?aPath\aPackage.jar;.?myJava.java
??????c:\>?java??-cp?aPath\aPackage.jar;.?myJava

????這種方法也有一個(gè)不方便的的地方就是當(dāng)?shù)谌桨诘穆窂捷^長或者需要兩個(gè)以上包的
時(shí)候,?每次編譯運(yùn)行都要寫很長,?非常不方便,?這時(shí)候可以寫腳本來解決.?比如一個(gè)例子:

??????compile???(文件,?權(quán)限改為可執(zhí)行,?當(dāng)前目錄)

??????$?cat?compile
---------------------------
??????#!/bin/bash

??????javac?-classpath?aPath\aPackage.jar:anotherPath\anotherPackage.jar:.?myJava.java
---------------------------
??????
??????run?(文件,?權(quán)限改為可執(zhí)行,?當(dāng)前目錄)

??????$cat?run
---------------------------
??????#!/bin/bash

??????java?-cp?aPath\aPackage.jar:anotherPath\anotherPackage.jar:.?myJava
---------------------------

??????或者:

??????compile.bat

??????c:\HelloWorld>?type?compile.bat
-------------------------??????
??????javac?-classpath?aPath\aPackage.jar:anotherPath\anotherPackage.jar:.?myJava.java
-------------------------
??????
??????run.bat

??????c:\HelloWorld>?type?run.bat
------------------------
??????java?-cp?aPath\aPackage.jar:anotherPath\anotherPackage.jar:.?myJava
------------------------
????就可以了.?試試看.?
????前面提到了擴(kuò)展類,?擴(kuò)展類是什么呢??java?的擴(kuò)展類就是應(yīng)用程序開發(fā)者用來
擴(kuò)展核心平臺(tái)功能的?java?類的包(或者是?native?code).?虛擬機(jī)能像使用系統(tǒng)類一
樣使用這些擴(kuò)展類.?有人建議可以把包放入擴(kuò)展目錄里,?這樣,?CLASSPATH?也不用設(shè)了,?
也不用指定了,?豈不是很方便??確實(shí)可以正確運(yùn)行,?但是個(gè)人認(rèn)為這樣不好,?不能什么
東西都往里擱,?一些標(biāo)準(zhǔn)的擴(kuò)展包可以,?比如,?JavaServlet,?Java3D?等等.?可以提個(gè)
建議,?加一個(gè)環(huán)境變量,?比如叫?JARPATH,?指定一個(gè)目錄,?專門存放用戶的?jar?zip
等包,?這個(gè)要等?SUN?公司來做了.?


????windows98?下,?我原來安裝的時(shí)候,?一直裝不上,?總是死機(jī),?好不容易裝上了,?缺
省的是不能運(yùn)行正確的,?然后把?tool.jar?放入?CLASSPATH?后工作正常.?現(xiàn)在作測試,
去掉仍然是正確的.?經(jīng)過多次測試,?發(fā)現(xiàn)如果原來曾裝過?jdk?的都很好,?沒有裝過的
裝的時(shí)候會(huì)死機(jī),?多裝幾次就可以了.?如果你發(fā)現(xiàn)正確安裝后,?不能正常工作,?就把
tools.jar?加入?CLASSPATH,?試一下.


二,?包?(package)

????Java?中的?"包"?是一個(gè)比較重要的概念,?package?是這樣定義的:

Definition:?A?package?is?a?collection?of?related?classes?and?interfaces?
that?provides?access?protection?and?namespace?management.

????也就是:?一個(gè)包就是一些提供訪問保護(hù)和命名空間管理的相關(guān)類與接口的集合.
????使用包的目的就是使類容易查找使用,?防止命名沖突,?以及控制訪問.
????這里我們不討論關(guān)于包的過多的東西,?只討論和編譯,?運(yùn)行,?類路徑相關(guān)的東西.
至于包的其他內(nèi)容,?請自己查閱相關(guān)文檔.

????簡單一點(diǎn)來說,?包就是一個(gè)目錄,?下面的子包就是子目錄,?這個(gè)包里的類就是
這個(gè)目錄下的文件.?我們用一個(gè)例子來說明.
????首先建目錄結(jié)構(gòu)如下:?PackageTest/source/,?以后根目錄指的是?PackageTest?
目錄,?我們的源程序放在?source?目錄下.?源程序如下:

PackageTest.java

package?pktest;

import?pktest.subpk.*;

public?class?PackageTest
{
????private?String?value;

????public?PackageTest(String?s)
????{
????????value?=?s;
????}

????public?void?printValue()
????{
????????System.out.println("Value?of?PackageTest?is?"?+?value);
????}

????public?static?void?main(String[]?args)
????{
????????PackageTest?test?=?new?PackageTest("This?is?a?Test?Package");
????????test.printValue();
????????PackageSecond?second?=?new?PackageSecond("I?am?in?PackageTest");
????????second.printValue();
????????PackageSub?sub?=?new?PackageSub("I?am?in?PackageTest");
????????sub.printValue();
????????System.exit(0);
????}
}

PackageSecond.java

package?pktest;

public?class?PackageSecond
{
????private?String?value;

????public?PackageSecond(String?s)
????{
????????value?=?s;
????}
????
????public?void?printValue()
????{
????????System.out.println("Value?of?PackageSecond?is?"?+?value);
????}
}

PackageSub.java

package?pktest.subpk;

import?pktest.*;

public?class?PackageSub
{
????private?String?value;

????public?PackageSub(String?s)
????{
????????value?=?s;
????}

????public?void?printValue()
????{
????????PackageSecond?second?=?new?PackageSecond("I?am?in?subpackage.");
????????second.printValue();
????????System.out.println("Value?of?PackageSub?is?"?+?value);
????}

}

Main.java

import?pktest.*;
import?pktest.subpk.*;

public?class?Main()
{
????public?static?void?main()
????{
????????PackageSecond?second?=?new?PackageSecond("I?am?in?Main");
????????second.printValue();
????????PackageSub?sub?=?new?PackageSub("I?am?in?Main");
????????sub.printValue();
????????System.exit(0);
????}
}
??
????其中,?Main.java?是包之外的一個(gè)程序,?用來測試包外的程序訪問包內(nèi)的類,
PackageTest.java?屬于?pktest?這個(gè)包,?也是主程序.?PackageSecond.java?也
屬于?pktest,?PackageSub?屬于?pktest?下的?subpk?包,?也就是?pktest.subpk.
詳細(xì)使用情況,?請參看源程序.
????好了,?先把源程序都放在?source?目錄下,?使?source?成為當(dāng)前目錄,?然后編
譯一下,?呵呵,?出錯(cuò)了,

Main.java:1:?Package?pktest?not?found?in?import.
import?pktest.*;

????這里涉及到類路徑中包是怎么查找的,?前面我們做了一點(diǎn)假設(shè):?"只要包含了
這個(gè)類就算找到了這個(gè)類",?現(xiàn)在就有問題了.?其實(shí)?jdk?的?工具?javac?java
javadoc?都需要查找類,?看見目錄,?就認(rèn)為是包的名字,?對于?import?語句來說,
一個(gè)包對應(yīng)一個(gè)目錄.?這個(gè)例子中,?import?pktest.*,?我們知道類路徑可以包
含一個(gè)目錄,?那么就以那個(gè)目錄為根,?比如有個(gè)目錄?/myclass,?那么就會(huì)在查找
/myclass/pktest?目錄及其下的類.?所有的都找遍,?如果沒有就會(huì)報(bào)錯(cuò).?由于現(xiàn)在
的類路徑只有當(dāng)前目錄,?而當(dāng)前目錄下沒有?pktest?目錄,?所以就會(huì)出錯(cuò).?類路徑
還可以包含?.jar?.zip?文件,?這些就是可以帶目錄的壓縮包,?可以把?.jar?.zip?
文件看做一個(gè)虛擬的目錄,?然后就和目錄一樣對待了.
????好了,?應(yīng)該知道怎么做了吧,?修改后的目錄結(jié)構(gòu)如下:

????PackageTest
????|
????|__source???Main.java
???????|
???????|__pktest???PackageTest.java???PackageSecond.java
??????????|
??????????|__subpk??PackageSub.java
???????
????然后重新編譯,?運(yùn)行,?哈哈,?通過了.?我們再來運(yùn)行一下?PackageTest.

????[source]$?java?pktest/PackageTest

????怎么又出錯(cuò)了??

Exception?in?thread?"main"?java.lang.NoClassDefFoundError:?pktest/PackageTest

????是這樣的,?java?所要運(yùn)行的是一個(gè)類的名字,?它可不管你的類在什么地方,?就象
我們前面所討論的一樣來查找這個(gè)類,?所以它把?pktest/PackageTest?看成是一個(gè)類的
名字了,?當(dāng)然會(huì)出錯(cuò)了,?應(yīng)該這么做,?

????[source]$?java?pktest.PackageTest

????大家應(yīng)該明白道理吧,?我就不多說了.?注意?javac?不一樣,?是可以指明源文件路徑
的,?javac?只編譯,?不運(yùn)行,?查找類也只有在源文件中碰到?import?時(shí)才會(huì)做,?與源文件
所在的包沒有關(guān)系.
????似乎還又些不好的地方,?怎么生成的?.class?文件這么分散呀,?看著真別扭.?別急,
javac?有一個(gè)?-d?命令行參數(shù),?可以指定一個(gè)目錄,?把生成的?.class?文件按照包給你
好好地?cái)R在這個(gè)目錄里面.

????[source]$?mkdir?classes
????[source]$?javac?-d?classes?pktest/PackageTest.java
????[source]$?javac?-d?classes?Main.java

????那么運(yùn)行怎么運(yùn)行呢??

????[source]$?cd?classes
????[classes]$?java?pktest.PackageTest
????[classes]$?java?Main

????就可以了.?其實(shí)?jdk?的這一套工具小巧簡單,?功能強(qiáng)大,?不會(huì)用或者用錯(cuò)其
實(shí)不關(guān)工具的事,?關(guān)鍵是明白工具背后的一些原理和必要的知識(shí).?集成環(huán)境是很好,?
但是它屏蔽了很多底層的知識(shí),?不出錯(cuò)還好,?一旦出錯(cuò),?如果沒有這些必要的知識(shí)
就很難辦,?只好上?bbs?問,?別人只告訴了你解決的具體方法,?下一次遇到稍微變化
一點(diǎn)的問題又不懂了.?所以不要拘泥于工具,?java?的這一套工具組合起來使用,?中
小型工程(五六十個(gè)類),?還是應(yīng)付得下來的.


三,?jar?文件

????以下把?.jar?.zip?都看做是?.jar?文件.

?
1,??從前面我們可以看出來?jar?文件在?java?中非常重要,?極大地方便了用戶的
使用.?我們也可以做自己的?.jar?包.
????還是使用前面那個(gè)例子,?Main.java?是包之外的東西,?用了?pktest?包中的類,
我們現(xiàn)在就是要把?pktest?做成一個(gè)?.jar?包,?很簡單,?剛才我們已經(jīng)把?pktest?
中的?.class?都集中起來了,?

????[classes]$?jar?-cvf?mypackage.jar?pktest

????就會(huì)生成?mypackage.jar?文件,?測試一下,?剛才我們生成的?Main.class?就在
????classes?目錄下,?所以,?從前面可以知道:

????[classes]$?java?-cp?mypackage.jar:.?Main

????就可以運(yùn)行了.

2,??如果你看過?jdk?所帶的例子,?你就會(huì)知道,?.jar?還可以直接運(yùn)行,?

????[/demo]$?java?-jar?aJar.jar

????那好,?就那我們的試一試,?

????[classes]$?java?-jar?mypackage.jar
????Failed?to?load?Main-Class?manifest?attribute?from
????mypackage.jar

????看來我們的?jar?和它的?jar?還不一樣,?有什么不一樣呢??拿它一個(gè)例子出來,
重新編譯,?生成?.jar?文件,?比較后發(fā)現(xiàn),?是?.jar?壓縮包中?META-INF/MANIFEST.MF
文件不一樣,?多了一行,?Main-Class:?xxxxx,?再看看出錯(cuò)信息,?原來是沒有指定?
Main-Class,?看看?jar?命令,?發(fā)現(xiàn)有一個(gè)參數(shù)?-m,?

????-m??include?manifest?information?from?specified?manifest?file

????和出錯(cuò)信息有點(diǎn)關(guān)系,?看來它要讀一個(gè)配制文件.?只好照貓畫虎寫一個(gè)了.

????[classes]$?cat?myManifest
????Manifest-Version:?1.0
????Main-Class:?pktest.PackageTest
????Created-By:?1.2.2?(Sun?Microsystems?Inc.)

????[classes]$?jar?cvfm?mypackage.jar?myManifest?pktest
????added?manifest
????adding:?pktest/(in?=?0)?(out=?0)(stored?0%)
????adding:?pktest/PackageSecond.class(in?=?659)?(out=?395)(deflated?40%)
????adding:?pktest/subpk/(in?=?0)?(out=?0)(stored?0%)
????adding:?pktest/subpk/PackageSub.class(in?=?744)?(out=?454)(deflated?38%)
????adding:?pktest/PackageTest.class(in?=?1041)?(out=?602)(deflated?42%)

????[classes]$?java?-jar?mypackage.jar
????Value?of?PackageTest?is?This?is?a?Test?Package
????Value?of?PackageSecond?is?I?am?in?PackageTest
????Value?of?PackageSecond?is?I?am?in?subpackage.
????Value?of?PackageSub?is?I?am?in?PackageTest

????好了,?成功了,?這樣就做好了一個(gè)可以直接執(zhí)行的?.jar?文件.?大家可以自己試一試
做一個(gè)以?Main?為主程序的可執(zhí)行的?jar.


小結(jié):

????這篇文章中,?我們討論了?java?中的?class?path,?package,?jar?等基本但比較
重要的東西,?主要是?class?path.?并不是簡單的一份?CLASSPATH?的完全功略,?而是
試圖讓讀者明白其原理,?自己思考,?自己動(dòng)手.?其實(shí)大多數(shù)東西都在?sun?的?java?doc?
中都有,?我只不過結(jié)合例子稍微談了一下,?希望能有所幫助.?由于條件所限,?只測試了?
jdk1.2.2?在?98?及?linux?的情況,?其他版本的?jdk?和平臺(tái)請大家自己測試,?錯(cuò)誤在
所難免,?還請指正.?

????下面是一些需要注意的問題:

1,?如果類路徑中需要用到?.jar?文件,?必須把?jar?文件的文件名放入類路徑,?而不是
其所在的目錄.
2,?在任何時(shí)候,?類名必須帶有完全的包名,?
3,?"."?當(dāng)前目錄最好在你的類路徑中.

????下面是一些常見的編譯和運(yùn)行的模式.

4.?To?compile?HelloWorld.java?app?in?the?default?package?in?C:\MyDir,?use
????????CD?\MyDir
????????????C:\jdk1.3\bin\Javac.exe?-classpath?.?HelloWorld.java
5.?To?run?a?HelloWorld.class?app,?in?the?default?package?in?C:\MyDir,?use
????????CD?\MyDir
????????????C:\jdk1.3\bin\Java.exe?-classpath?.?HelloWorld
6.?To?run?a?HelloWorld.class?app,?in?the?default?package?in?a?jar?in?C:\MyDir,?use
????????CD?\MyDir
????????????C:\jdk1.3\bin\Java.exe?-classpath?HelloWorld.jar?HelloWorld
7.?To?compile?a?HelloWorld.java?app?in?C:\MyPackage,?in?package?MyPackage,?use
????????CD?\
????????????C:\jdk1.3\bin\Javac.exe?-classpath?.?MyPackage\HelloWorld.java
8.?To?run?a?HelloWorld.class?app?in?C:\MyPackage,?in?package?MyPackage,?use
????????CD?\
????????????C:\jdk1.3\bin\Java.exe?-classpath?.?MyPackage.HelloWorld
9.?To?run?a?HelloWorld.class?app?in?C:\MyPackage,?in?a?jar?in?package?MyPackage,?use
????????CD?\MyDir
????????????C:\jdk1.3\bin\Java.exe?-classpath?HelloWorld.jar?MyPackage.HelloWorld

(注:?default?package?指的是在程序中不指定任何包).

????最后一個(gè)小小的建議,?把?sun?的?jdk?tools?documentation?好好地看一看,?
把?jdk?的那些工具?java?javac?javadoc?jar?javap?jdb......好好用一用,?會(huì)
有好處的.?The?Simplest?Is?The?Best.

總結(jié)

以上是生活随笔為你收集整理的java classpath import package 机制 @Java的ClassPath, Package和Jar的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。