25 環境變數及命令列變數、選項引數設定
之前於「開發環境」章節中已簡單說明過環境變數,但環境變數及其引數甚為繁雜,特闢專章說明,主要以Windows 7為例。
Windows 7、10可進入[控制台] ->[系統及安全性]->[系統]->[進階]->[環境變數]新增環境變數或編輯現有環境變數,選擇user的使用者環境變數時,效用僅限於該使用者,如選擇系統環境變數,則適用於全部使用者。
環境變數有PATH、CLASSPATH等,並有命令列選項引數-sourcepath及-d,其關係圖如下,功能及使用方式詳述如後。
[25-1 PATH環境變數]
為作業系統使用之環境變數,設定Windows執行檔.exe、bat之搜尋路徑,編譯程式javac.exe及執行程式java.exe須放置於該路徑上方可執行。
環境變數名稱:PATH
變數值:C:\Program Files\Java\jdk1.8.0_11\bin等。(預設C:\Windows\system32)
bin為JDK下載後放置javac等之資料夾。jdk資料夾名稱視下載時版本而定。
適用時機為執行javac時,會自動搜尋此一資料夾。
定義多個變數值時,須以;(分號)隔開,並會依序尋找,使用第一個找到者。
[javac及java]
程式名 |
安裝後之PATH |
備註 |
javac |
C:\Program Files\Java\jdk1.8.0_11\bin |
紅字部分依版本而異 |
java |
C:\Windows\system32 |
預設 |
[25-1-1 PATH設定方式]
[命令列變數]
使用命令列set指令設定PATH,可設定多個值,搜尋時會依序尋找,使用第一個找到者。以命令列指令設定者,優先於系統環境變數及使用者環境變數所設定者。有效期間為設定後直到命令列關閉,下次開啟命令列時須重新設定。
設定例:假設欲編譯之原始程式碼Main22.java存放於C:\js資料夾,但未設
定編譯程式javac之PATH,則須指定完整路徑。
<錯誤(未設定)>C:\js>javac main22.java.....找不到javac
<正確(未設定)>C:\js>"C:\Program Files\Java\jdk1.8.0_11\bin \javac" main22.java
<正確>C:\js>set PATH=C:\Program Files\Java\jdk1.8.0_11\bin
C:\js>javac main22.java
[系統環境變數]
Windows 7、10可進入[控制台] ->[系統及安全性]->[系統]->[進階]->[環境變數]新增或編輯系統環境變數PATH,尚未設定其他變數值時使用新增功能,已有設定者使用編輯功能插入變數值。可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者,常用者可置於前面。系統環境變數優先於使用者環境變數。
新增或編輯例:輸入C:\Program Files\Java\jdk1.8.0_11\bin
命令列編譯輸入例:C:\js>javac main22.java
[使用者環境變數]
Windows 7、10可進入[控制台] ->[系統及安全性]->[系統]->[進階]->[環境變數]新增或編輯使用者環境變數PATH。尚未設定其他變數值時使用新增功能,已有設定者使用編輯功能插入變數值。可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者,常用者可置於前面。
新增或編輯例:輸入C:\Program Files\Java\jdk1.8.0_11\bin
命令列編譯輸入例:C:\js>javac main22.java
[環境變數編輯範例]
原有變數值:C:\Windows\system32
編輯後變數值:C:\Program Files\Java\jdk1.8.0_11\bin;C:\Windows\system32
(插入紅字部分)
[25-1-2 PATH的選擇原則]
PATH的選擇原則如下圖:
[25-2 CLASSPATH]
為JVM使用之環境變數。指定原始程式碼編譯(javac指令)時及執行(java指令)時,位元檔(.class檔)的輸入來源資料夾,而非輸出資料夾。
環境變數名稱:CLASSPATH
變數值:自定,預設為目前的資料夾
適用時機為javac編譯或java執行時指定byte code(.class檔)之輸入路徑。
[25-2-1 CLASSPATH設定方式]
[命令列選項引數]
使用命令列選項引數-cp(classpath)設定CLASSPATH,可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者。以命令列選項引數設定者,優先於命令列變數、系統環境變數及使用者環境變數所設定者。有效期間為該次執行javac或java指令,下次執行時須於javac、java指令再指定該選項引數。
指定格式:javac |java -cp 資料夾 主類別名稱
指定例:C:\js1>java –cp npub1 npubMain22
資料夾指定格式可分為相對位置及絕對位置,如目前資料夾為C:\js1,
相對位置例(同上):C:\js1>java –cp npub1 npubMain22
絕對位置例:C:\js1>java –cp C:\js1\npub1 npubMain22
[命令列變數]
使用命令列set指令設定CLASSPATH,可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者。以命令列指令設定者,優先於系統環境變數及使用者環境變數所設定者。有效期間為設定後直到命令列關閉,下次開啟命令列時須重新設定。
指定格式:set classpath=資料夾
指定例:C:\js1>set classpath=npub1
C:\js1>java npubMain22
資料夾指定格式可分為相對位置及絕對位置,如目前資料夾為C:\js1,
相對位置例:C:\js1>set classpath=npub1
絕對位置例:C:\js1>set classpath=C:\js1\npub1
[系統環境變數]
Windows 7、10可進入[控制台] ->[系統及安全性]->[系統]->[進階]->[環境變數]新增或編輯系統環境變數CLASSPATH。可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者。系統環境變數優先於使用者環境變數。
系統環境變數CLASSPATH新增及編輯方式同PATH。
[使用者環境變數]
Windows 7、10可進入[控制台] ->[系統及安全性]->[系統]->[進階]->[環境變數]新增或編輯使用者環境變數CLASSPATH。可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者。
使用者環境變數CLASSPATH新增及編輯方式同PATH。
[25-2-2 CLASSPATH的選擇原則]
CLASSPATH的選擇原則如下圖:
[25-2-3 編譯時.class檔之輸出資料夾]
執行javac編譯時,其.java來源資料夾依後述SOURCEPATH選擇原則,.class輸出資料夾則為當時資料夾或依-d選項引數指定。
[原始碼檔內容]
檔名:class_m1.java
class class_a1 { int x = 10; }
class class_m1{
public static void main(String[] args){
class_a1 obj1 = new class_a1();
obj1.x = obj1.x + 1;
System.out.println("x的值為" + obj1.x); } }
檔名:class_m2.java
class class_a2 { int x = 10; }
class class_m2{
public static void main(String[] args){
class_a2 obj1 = new class_a2();
obj1.x = obj1.x + 2;
System.out.println("x的值為" + obj1.x); } }
檔名:class_m3.java
class class_a3 { int x = 10; }
class class_m3{
public static void main(String[] args){
class_a3 obj1 = new class_a3 ();
obj1.x = obj1.x + 3;
System.out.println("x的值為" + obj1.x); } }
檔名:class_m4.java
class class_a4 { int x = 10; }
class class_m4{
public static void main(String[] args){
class_a4 obj1 = new class_a4 ();
obj1.x = obj1.x + 4;
System.out.println("x的值為" + obj1.x); } }
[原始碼、位元碼皆位於執行時資料夾-不指定-d選項引數時]
原始碼來源資料夾js1:class_m1.java
位元碼輸出資料夾js1:class_m1.class、class_a1.class
[執行例]
C:\js1>javac class_m1.java
C:\js1>java class_m1
x的值為11
[原始碼位於執行時資料夾,位元碼置於指定-d選項引數之資料夾-相對路徑]
-d所指定之資料夾必須為已經存在。
原始碼來源資料夾js1:class_m2.java
位元碼輸出資料夾js1\npub1:class_m2.class、class_a2.class
[執行例]
C:\js1>javac -d npub1 class_m2.java
C:\js1>cd C:\js1\npub1
C:\js1\npub1>java class_m2
x的值為12
[原始碼位於執行時資料夾,位元碼置於指定-d選項引數之資料夾-絕對路徑1]
-d所指定之資料夾必須為已經存在。
原始碼來源資料夾js1:class_m3.java
位元碼輸出資料夾js1\npub1:class_m3.class、class_a3.class
[執行例]
C:\js1>javac -d C:\js1\npub1 class_m3.java
C:\js1>cd C:\js1\npub1
C:\js1\npub1>java class_m3
x的值為13
[原始碼位於執行時資料夾,位元碼置於指定-d選項引數之資料夾-絕對路徑2]
-d所指定之資料夾必須為已經存在。
原始碼來源資料夾js1:class_m4.java
位元碼輸出資料夾ctcsource1:class_m4.class、class_a4.class
[執行例]
C:\js1>javac -d C:\ctcsource1 class_m4.java
C:\js1>cd C:\ctcsource1
C:\ctcsource1>java class_m4
x的值為14
[25-2-4 javac、java指令與CLASSPATH]
java程式編譯及執行時以classpath指定位元檔之來源資料夾。
原始碼來源資料夾js1:cpsub1.java、cpmain1.java
位元碼輸出資料夾js1\npub1:cpsub1.class
//檔名cpsub1.java,資料夾C:\js1
public class cpsub1 {
int a = 10;
void pr1() {
System.out.println("a = " + a); } }
//檔名cpmain1.java,資料夾C:\js1
class cpmain1 {
public static void main(String[] args){
cpsub1 ph = new cpsub1();
ph.pr1(); } }
[編譯時指定輸出資料夾]
C:\js1>javac -d npub1 cpsub1.java
將資料夾js1中cpsub1.java編譯至資料夾js1\npub1為cpsub1.class。
[編譯時不指定輸出資料夾]
C:\js1>javac cpmain1.java
將資料夾js1中cpmain1.java編譯至資料夾js1為cpmain1.class,因未指定classpath而找不到cpsub1.class,故會將資料夾js1內之cpsub1.java再編譯至同一資料夾js1內。
C:\js1>java cpmain1
a = 10
刪除資料夾js1中之cpsub1.java、cpsub1.class及cpmain1.class。
[範例-錯誤]
C:\js1>javac cpmain1.java
將資料夾js1中cpmain1.java編譯,因找不到cpsub1.class及cpsub1.java,因而編譯錯誤。
C:\js1>javac cpmain1.java
cpmain1.java:3: error: cannot find symbol
cpsub1 ph = new cpsub1();
^
symbol: class cpsub1
location: class cpmain1
cpmain1.java:3: error: cannot find symbol
cpsub1 ph = new cpsub1();
^
symbol: class cpsub1
location: class cpmain1
2 errors
[範例]
C:\js1>javac -cp npub1 cpmain1.java
因指定classpath而找到cpsub1.class,並將資料夾js1中cpmain1.java編譯至資料夾js1為cpmain1.class。
[範例-錯誤]
C:\js1>java cpmain1
因沒指定cpsub1.class所在資料夾,故找不到cpsub1.class,發生下述錯誤。
Exception in thread "main" java.lang.NoClassDefFoundError: cpsub1
at cpmain1.main(cpmain1.java:3)
Caused by: java.lang.ClassNotFoundException: cpsub1
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
[範例-錯誤]
C:\js1>java -cp npub1 cpmain1
錯誤: 找不到或無法載入主要類別 cpmain1
因-cp只指定cpsub1.java所在資料夾,故發生上述錯誤。
[範例-相對路徑]
C:\js1>java -cp .;npub1 cpmain1
a = 10
以-cp指定.(現行資料夾,存放cpmain1.class)及npub1(cpsub1.class存放資料夾)即可執行。
[範例-絕對路徑]
C:\js1>java -cp C:\js1;C:\js1\npub1 cpmain1
a = 10
指定絕對路徑亦同。
[25-3 SOURCEPATH]
為編譯程式javac使用之命令列指令選項引數。指定原始程式碼編譯(javac指令)的原始檔(.java檔)之輸入來源資料夾。
命令列指令選項引數:sourcepath(前置-)
變數值:自定
適用時機為javac編譯source code(.java檔)之輸入路徑。
[25-3-1 SOURCEPATH設定方式]
[命令列選項引數]
使用命令列選項引數-sourcepath設定原始碼檔資料夾,可設定多個值,以;(分號)區隔,搜尋時會依序尋找,使用第一個找到者。有效期間為該次執行之javac指令,下次執行時須於javac指令再指定該選項引數。
指定格式:javac -sourcepath 資料夾所屬資料夾\主類別名稱.java
指定例:C:\js1>javac -sourcepath npub1 npub1\Main22
注意:須加入所屬資料夾。
資料夾指定格式可分為相對位置及絕對位置,如目前資料夾為C:\js1,
相對位置:C:\js1>javac -sourcepath npub1 npub1\Main22
絕對位置:C:\js1>javac -sourcepath C:\js1\npub1 npub1\Main22
[25-3-2 SOURCEPATH的選擇原則]
編譯/執行時原始碼檔及位元碼檔資料夾之關聯如下二表:
表25-1 單一類別檔案
單一/複數 類別檔 |
一般類別/ 主類別 |
一般類別 資料夾 |
主類別 資料夾 |
一般及主類別資料夾 |
sourcepath 指定 |
編譯執行 時資料夾 |
.java來源 資料夾 |
單一 |
一般類別 |
A |
|
|
|
A |
A |
單一 |
主類別 |
|
A |
|
|
A |
A |
單一 |
一般類別 |
B |
|
|
|
A |
編譯錯誤 |
單一 |
主類別 |
|
B |
|
|
A |
編譯錯誤 |
單一 |
一般類別 |
A |
|
|
B |
A |
編譯錯誤 |
單一 |
主類別 |
|
A |
|
B |
A |
編譯錯誤 |
單一 |
一般類別 |
B |
|
|
B |
A |
B |
單一 |
主類別 |
|
B |
|
B |
A |
B |
單一 |
一般+主 |
|
|
A |
|
A |
A |
單一 |
一般+主 |
|
|
A |
B |
A |
編譯錯誤 |
單一 |
一般+主 |
|
|
B |
B |
A |
B |
表25-2 複數類別檔案-一般類別、主類別各成單一檔案,主類別會實作一般類別
單一/複數 類別檔 |
一般類別/ 主類別 |
一般類別 資料夾 |
主類別 資料夾 |
一般類別 .class檔 |
sourcepath 指定 |
編譯執行 時資料夾 |
.java來源 資料夾 |
複數 |
一般類別 |
A |
|
A |
|
A |
A |
主類別 |
|
A |
|
||||
複數 |
一般類別 |
B |
|
|
|
A |
編譯錯誤 |
主類別 |
|
|
|
||||
複數 |
一般類別 |
B |
|
|
B |
A |
編譯錯誤 |
主類別 |
|
A |
|
||||
複數 |
一般類別 |
B |
|
|
A;B |
A |
B |
主類別 |
|
A |
|
A |
|||
複數 |
一般類別 |
B |
|
|
B |
A |
B |
主類別 |
|
B |
|
上述表格僅為部分舉例。
紅字為二者有存在其一,或兩者皆存在。
主類別編譯時,一般類別的.class檔或.java檔所在之資料夾須指定正確。
[範例原始檔內容]
.java檔:class_m5.java
class class_a5 { int x = 20; }
class class_m5{
public static void main(String[] args){
class_a5 obj1 = new class_a5 ();
obj1.x = obj1.x + 5;
System.out.println("x的值為" + obj1.x); } }
.java檔:class_m6.java
class class_a6 { int x = 20; }
class class_m6{
public static void main(String[] args){
class_a6 obj1 = new class_a6 ();
obj1.x = obj1.x + 6;
System.out.println("x的值為" + obj1.x); } }
.java檔:class_m7.java
class class_a7 { int x = 20; }
class class_m7{
public static void main(String[] args){
class_a7 obj1 = new class_a7 ();
obj1.x = obj1.x + 7;
System.out.println("x的值為" + obj1.x); } }
[無sourcepath選項引數設定時,適用執行時資料夾]
.java檔:class_m5.java
存放資料夾:C:\js1
執行時資料夾:C:\js1
[範例]
C:\js1>javac class_m5.java
C:\js1>java class_m5
x的值為25
[sourcepath 設定C:\js1\npub1,適用該資料夾]
.java檔:class_m6.java
存放資料夾:C:\js1\npub1
執行時資料夾:C:\js1
[相對路徑]
C:\js1>javac -sourcepath npub1 class_m6.java
javac: file not found: class_m6.java
Usage: javac <options> <source files>
use -help for a list of possible options
class_m6.java前沒加上資料夾名稱
C:\js1>javac -sourcepath npub1 npub1\class_m6.java
C:\js1>java -cp npub1 class_m6
x的值為26
[絕對路徑]
C:\js1>javac -sourcepath C:\js1\npub1 npub1\class_m6.java
C:\js1>javac -sourcepath C:\js1\npub1 C:\js1\npub1\class_m6.java
C:\js1>java -cp npub1 class_m6
x的值為26
[原始檔和位元檔分開存放]
原始檔(.java檔)和位元檔(.class檔)混在同一資料夾較難管理,一般將其分別存放在不同之資料夾裡。
[sourcepath 設定C:\js1\npub1,-d設定C:\ctcsource1]
.java檔:class_m6.java
原始檔存放資料夾:C:\js1\npub1
位元檔存放資料夾:C:\ctcsource1
執行時資料夾:C:\js1
[執行例]
C:\js1>javac -sourcepath npub1 -d C:\ctcsource1 npub1\class_m7.java
C:\js1>java -cp C:\ctcsource1 class_m7
x的值為27
留言列表