2017年4月21日 星期五

java 編譯/執行環境 (1) - 引用別的檔案的 class

再來要說明怎麼把程式碼分開到不同的檔案, 並引用不同檔案的 class, 編譯與執行的動作開怎麼進行。

由於 java 奇怪的路徑尋訪, 我必須列出我目前在那個目錄, 避免我自己搞不清楚到底為什麼又找不到 class 了。

我在那個目錄
/home/descent/git/progs/java/DescentPackage
descent@debian64:DescentPackage$ ls *.java
HelloWorld.java  PrintString.java

按照 java 規定, 只能有一個 main method, 所以 HelloWorld.java 相當於 c++ main 的程式進入點, java 程式就是從這裡開始執行。

由於使用了 DescentPackage 這個 namespace, 所以這兩個檔案都得建立在 DescentPackage (按, 好蠢, java 還建議用 com.google.www 這種 namespace, 辛苦你了, 得建立不少層目錄, 你一定靠 IDE 搞定這事吧, 但手工打造一次, 你才能體會這種愚蠢) 這個目錄裡頭。

HelloWorld.java L8 使用了 PrintString 這個 class, 這個 class 在別的檔案裡頭, 所以用上了 L2 的 import, 所以實際上這個 class 全名是 DescentPackage.PrintString。不用 import 的話, 得改成

DescentPackage.PrintString ps = new DescentPackage.PrintString();

很長, 我知道。

HelloWorld.java
 1 package DescentPackage;
 2 import DescentPackage.*;
 3 
 4 public class HelloWorld
 5 {
 6   public static void main(String[] args) 
 7   {
 8     PrintString ps = new PrintString();
 9     System.out.println("Hello World");
10     ps.msg();
11   }
12 }


那這個 PrintString.java 要怎麼寫呢? class name 要和檔名一樣 (還是覺得很蠢的設計), 我很討厭大小寫混在一起的檔名, 因為在 linux 這種有區分大寫的檔名的檔案系統, 這很麻煩 (c/c++ 的 header files), 我通常會用全小寫檔名, 而多按 shift 也很討厭, 你們用 GUI 的都不知道打檔名的辛苦。

然後只能有一個 public class, 挪, 就像 PrintString.java 那樣。
PrintString.java
1 package DescentPackage;
2 
3 public class PrintString
4 {
5   public void msg()
6   {
7     System.out.println("XX Hello World");
8   }
9 }

程式寫好了又來到頭痛的編譯問題, 這要怎麼編譯呢?

可以在 DescentPackage/ 上一層編譯

cent@debian64:java$ pwd
/home/descent/git/progs/java
descent@debian64:java$ ls
DescentPackage/
$ javac DescentPackage/HelloWorld.java

也可以在 DescentPackage/ 這層編譯

descent@debian64:DescentPackage$ pwd
/media/work/git/progs/java/DescentPackage
descent@debian64:DescentPackage$ javac -cp .. HelloWorld.java 

比 c++ 聰明的是, javac 會把相關的 java source code 也編譯成 .class, 所以打一次 javac 會得到 HelloWorld.class PrintString.class 2 個 class 檔案。

編譯完成, 再來是頭痛的執行問題:

descent@debian64:java$ pwd
/home/descent/git/progs/java
descent@debian64:java$ java  DescentPackage.HelloWorld 
yy Hello World
XX Hello World
descent@debian64:java$ cd DescentPackage/
descent@debian64:DescentPackage$ java -cp .. DescentPackage.HelloWorld 
yy Hello World
XX Hello World

這是很簡單的範例, 如果使用多個 package namespace, 就得好好檢視每個 class 是不是都可被搜尋到。

javac, java man page
1 javac [ options ] [ sourcefiles ] [ classes] [ @argfiles ]
2
3 java [options] classname [args]
4 java [options] -jar filename [args]

要針對 java 檔案來執行程式, 得用 jar 的方式, 下回我們來挑戰 jar。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。