java -jar與java -cp
- 1、情景描述
- 2、情景分析
- 3、兩者區別
通常情況下,我們會看到以下兩種命令啟動的Java程序:
java -jar xxx.jar [args]
java -cp xxx.jar mainclass [args]
這兩種用法有什么區別呢?
1、情景描述
1)Java打包單個類
例如,在com.test
下有一個文件Hello.java
,在test
目錄CMD命令行下執行編譯:
javac Hello.java
在com
上層目錄CMD命令行執行單個類打jar
包命令:
java -cvf test.jar com
2)分別執行java -jar和java -cp
執行java -jar
命令:
java -jar test.jar Tom
# test.jar中沒有主清單屬性
執行java -cp
命令:
java -cp test.jar com.test.Hello Tom
# Hello Tom
也就是java -jar
命令執行報錯,java -cp
命令執行成功。這是什么原因呢?
2、情景分析
首先jar
包實際上和zip
壓縮文件是一樣的,我們甚至完全可以用zip
壓縮工具來壓縮com
目錄,然后用java -cp com.zip com.test.Hello Tom
運行。不同的是,使用java
命令打出的jar
包會多出來一個東西:META-INF
目錄
該目錄里面有一個MANIFEST.MF
文件,這個文件就是jar
的主清單文件。java -jar
提示“沒有主清單屬性”,就是因為主清單文件中缺失了一個屬性:Main-Class
,它聲明了jar
包的默認入口類,也就是java -jar
運行時開始執行的類,其格式為:
Main-Class: com.test.Hello
如果我們在MANIFEST.MF
文件中添加上述屬性,java -jar
將執行成功。需要注意的是,該屬性冒號后面有一個空格,且屬性結束必須換行
當然,在打jar
包時可以通過-e
參數指定默認入口類(自動生成Main-Class
屬性),在com
上層目錄CMD命令行執行單個類打jar
包命令:
java -cvfe test.jar com.test.Hello com
執行java -jar
命令:
java -jar test.jar Tom
# Hello Tom
3、兩者區別
使用java -jar
運行jar
包時,虛擬機將忽略系統中的classpath
配置,如果有依賴jar
,需要在主清單屬性中指定,格式為:
Class-Path: xx01.jar xx02.jar org/xx03.jar
多個jar
包之間使用空格隔開,其路徑是相對于當前運行jar
包所在的目錄
使用java -cp
運行jar
包時,cp
本身就是classpath
的意思,依賴多個jar
時,直接在命令中指定,格式為:
java -cp test.jar;xx01.jar;xx02.jar com.test.Hello
值得注意的是,多個jar
包之間的分隔符在Windows上是;
,而在Linux中是:
綜上所述,java -jar
命令與java -cp
命令的區別總結如下:
-
java -jar:用來執行可執行
jar
,其可執行性由jar
包中的主清單屬性Main-Class
決定 -
java -cp:純粹的
java
命令,在指定classpath
下查找Java類文件并執行,使用更靈活
參考文章:https://blog.csdn.net/firstendhappy/article/details/119209167