每個 Java 範例都是獨立的 Main.java,可用 JDK 11 編譯執行;請一次複製一個範例。題庫使用 public class Solution 中的 public static solve(...) 方法,請保留題目指定的型別與參數,使用 return 交回答案,不必另外讀取輸入或撰寫 main。
01|程式從 main 開始
Java 用 class 描述類別;類別中可宣告欄位與方法。main 是啟動程式的進入點,public static void main(String[] args) 的大小寫、參數與回傳型別都要保留。static 代表屬於類別,void 代表沒有回傳值。
將下例存成 Main.java,使用 JDK 11 的 javac 編譯,再用 java 執行。public 類別名稱必須與檔名一致;每個敘述通常以半形分號結尾,區塊使用大括號。System.out.println 會在輸出後換行,print 則不會。
public class Main {
public static void main(String[] args) {
System.out.println("開始學習 Java 11");
System.out.print("每天練習 ");
System.out.println(10 + " 分鐘");
}
}開始學習 Java 11 每天練習 10 分鐘
javac -encoding UTF-8 --release 11 Main.java
java Main教材對照:PDF 第 4–12 頁
02|欄位、區域變數與有回傳值的方法
欄位寫在類別中;區域變數寫在方法或建構子中。static 欄位由類別共用,實例欄位由各物件各自持有。區域變數使用前必須先指定值,不能以 static 修飾。
方法宣告會說明回傳型別與參數。下例 total 回傳 int,因此用 return 交回計算結果;呼叫者可以接住回傳值再列印。方法只列印結果,不代表有回傳值。
public class Main {
static final String COURSE = "Java 11";
static int total(int price, int quantity) {
return price * quantity;
}
public static void main(String[] args) {
int amount = total(25, 4);
System.out.println(amount);
System.out.println(COURSE);
}
}100 Java 11
教材對照:PDF 第 7–12、28–30 頁
03|註解、命名與存取範圍
// 是單行註解,/* ... */ 是區塊註解,/** ... */ 可供 javadoc 產生說明文件。@Override 等 annotation 是給工具或執行環境的中繼資料,與一般註解的功能不同。
類別慣用大駝峰命名,例如 StudentAccount;方法與變數慣用小駝峰,例如 getScore、totalPrice;常數慣用 MAX_SIZE。名稱區分大小寫、不能以數字開頭,也不能使用 class 等關鍵字。Java 11 不允許單獨以 _ 作為名稱。
- private:限所在頂層類別範圍內存取,包含其中的巢狀類別。
- 無修飾字:同一 package 可存取,這是 package-private,宣告時不寫 default。
- protected:同套件可存取;跨套件子類別須遵守繼承與接收物件型別的限制。
- public:公開存取;本課使用一般 classpath 專案,不涉及模組匯出的額外限制。
- 頂層類別只能使用 public 或無存取修飾字。getter/setter 是方法命名慣例,仍應檢查資料是否合法。
教材對照:PDF 第 13–15、24–27 頁
04|package、import、classpath 與 JAR
原始檔的順序是 package 宣告、import 宣告、類別宣告。package school.demo; 定義套件名稱;import java.util.Scanner; 讓程式使用簡短類別名。import 的 * 只涵蓋指定套件內的型別,不會自動包含子套件;package 宣告不能帶 *。java.lang 中的 String、System 等型別可直接使用。
classpath 是尋找應用程式類別與 JAR 的根目錄或檔案清單。若 Main.java 第一行寫 package school.demo;,執行 javac -d out Main.java 後,須從套件根目錄以 java -cp out school.demo.Main 執行。Windows 多個 classpath 項目用分號,macOS/Linux 用冒號分隔。
JAR 可將編譯後的類別與資源包成一個檔案,META-INF/MANIFEST.MF 可記錄 Main-Class 等資訊。以下命令使用本章第一節沒有 package 的 Main.java;--main-class 會設定啟動類別。JDK 11 的標準函式庫以模組提供,不再使用舊教材中的 rt.jar/tools.jar 路徑。
javac -encoding UTF-8 --release 11 Main.java
jar --create --file lesson.jar --main-class Main Main.class
jar --list --file lesson.jar
java -jar lesson.jar教材對照:PDF 第 16–23、69–72 頁
05|八種基本資料型別與字面值
Java 的八種基本型別為 byte、short、int、long、float、double、char、boolean。整數字面值通常是 int,小數通常是 double;較大的整數可加 L,float 字面值要加 F。char 用單引號,String 用雙引號;boolean 只能是 true 或 false,不能把 0、1 當作布林值。
- byte/short/int/long 分別為 8/16/32/64 位元帶正負號整數;int 範圍為 -2,147,483,648 到 2,147,483,647。
- char 是 16 位元 UTF-16 碼元,不保證一個 char 就能表示所有 Unicode 字元;某些表情符號需要兩個碼元。
- 欄位與新陣列元素有預設值:數值 0、boolean 為 false、參考為 null;區域變數不能直接套用這個規則。
- 0b 開頭是二進位、0x 是十六進位、0 開頭的整數可表示八進位;數字中的底線只為方便閱讀。
public class Main {
public static void main(String[] args) {
byte small = 12;
short count = 300;
int amount = 30_000;
long large = 2_147_483_648L;
float ratio = 1.5F;
double average = 7.0 / 2;
char grade = 'A';
boolean ready = true;
System.out.println(small + count + amount);
System.out.println(large);
System.out.println(ratio + " " + average);
System.out.println(grade + " " + ready);
System.out.println(0b1101 + " " + 0x2F + " " + 071);
}
}30312 2147483648 1.5 3.5 A true 13 47 57
教材對照:PDF 第 28–38 頁
06|轉型、整數除法與浮點誤差
整數除法會向零截去小數,7 / 2 是 3;要取得 3.5,需讓其中一個運算元成為浮點數。byte、short、char 的一般整數運算會先提升為 int;轉回較小型別時可能失去資料。強制轉型是接受轉換規則,不是保證結果符合原意。
int 轉 long 不會失去整數精度,但某些整數轉 float/double 可能失去低位精度,因此不能把所有自動轉型都視為完全無損。float/double 的部分十進位小數是近似值;需要精確十進位運算時,可用字串建立 BigDecimal。
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
System.out.println(7 / 2);
System.out.println(7 / 2.0);
System.out.println(-7 / 2);
System.out.println((int) 3.9);
System.out.println((byte) 257);
System.out.println(0.3 + 0.3 + 0.3 == 0.9);
BigDecimal value = new BigDecimal("0.3");
System.out.println(value.add(value).add(value));
}
}3 3.5 -3 3 1 false 0.9
教材對照:PDF 第 35–40、55–56 頁
07|運算子、短路與先後順序
= 是指定,== 是比較。算術包含 +、-、*、/、%;比較包含 <、<=、>、>=、==、!=。&&、|| 有短路效果,&、| 用在布林值時會計算兩邊。條件 ? A : B 依條件選擇一個值。先用括號寫清楚意圖,再思考如何簡化。
- 後置 value++ 先產生舊值,再遞增;前置 ++value 先遞增,再產生新值。避免一行修改同一變數多次。
- 整數的 &、|、^、~ 分別做位元 AND、OR、XOR、反相;<< 左移、>> 帶符號右移、>>> 補零右移。
- a += b 會把結果轉回 a 的型別;對 byte 等型別而言,不能完全當成 a = a + b。
- 字串 + 由左至右組合;數值計算與文字混用時用括號保留原意。
public class Main {
public static void main(String[] args) {
int value = 3;
System.out.println(value++);
System.out.println(++value);
int denominator = 0;
boolean valid = denominator != 0 && 12 / denominator > 2;
System.out.println(valid);
System.out.println(value >= 5 ? "達標" : "繼續練習");
System.out.println("總數=" + 2 + 5);
System.out.println("總數=" + (2 + 5));
System.out.println(6 & 3);
System.out.println(1 << 3);
}
}3 5 false 達標 總數=25 總數=7 2 8
教材對照:PDF 第 54–66 頁
08|String 的內容比較與不可變性
String 是參考型別。== 比較兩個參考是否指向同一物件;equals 比較字串內容,equalsIgnoreCase 則忽略大小寫。字面值可能共用字串池中的實例,但程式判斷文字內容仍應用 equals。字串不可變,串接會得到另一個結果,不會改掉先前字串。
public class Main {
public static void main(String[] args) {
String first = new String("Java");
String second = new String("Java");
String original = first;
System.out.println(first == second);
System.out.println(first.equals(second));
System.out.println("JAVA".equalsIgnoreCase(first));
first = first + " 11";
System.out.println(original);
System.out.println(first.length());
System.out.println(first.charAt(0));
}
}false true true Java 7 J
教材對照:PDF 第 41–49 頁
09|陣列、二維陣列與複製
陣列長度建立後固定,索引從 0 到 length - 1。二維陣列其實是陣列中的陣列,各列可以長度不同。陣列取長度用 .length,字串則是 .length()。System.arraycopy 複製指定區段;Arrays.copyOf 可建立不同長度的新陣列。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] scores = {70, 80, 90};
int[] copied = Arrays.copyOf(scores, 4);
copied[0] = 100;
int[][] rows = {{1, 2}, {3, 4, 5}};
System.out.println(scores[0]);
System.out.println(Arrays.toString(copied));
System.out.println(rows.length + " " + rows[1].length);
System.out.println(rows[1][2]);
int[] part = new int[2];
System.arraycopy(scores, 1, part, 0, 2);
System.out.println(Arrays.toString(part));
}
}70 [100, 80, 90, 0] 2 3 5 [80, 90]
教材對照:PDF 第 42–53 頁
10|Java 一律傳值
方法參數取得的是值的副本。基本型別複製數值;參考型別複製參考值,因此方法可透過該參考修改同一陣列中的元素。但重新指定參數變數,不會讓呼叫端的變數改指向另一個物件。
public class Main {
static void change(int number, int[] values) {
number = 99;
values[0] = 8;
values = new int[] {100};
}
public static void main(String[] args) {
int number = 5;
int[] values = {5};
change(number, values);
System.out.println(number);
System.out.println(values[0]);
}
}5 8
教材對照:PDF 第 67–68 頁
11|Scanner 讀取資料與換行
Scanner 可從 System.in 讀取輸入,也能分析一段字串。nextInt、nextDouble、nextBoolean 讀取對應型別;next 以空白分隔取得一段文字,nextLine 則讀到該行結尾。下例使用固定字串,讓你直接執行並比對輸出。
import java.util.Scanner;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner("18 Java 3.5\n完整的一行文字\n");
input.useLocale(Locale.ROOT);
int count = input.nextInt();
String language = input.next();
double hours = input.nextDouble();
input.nextLine();
String message = input.nextLine();
System.out.println(count + " " + language + " " + hours);
System.out.println(message);
input.close();
}
}18 Java 3.5 完整的一行文字
教材對照:PDF 第 73–75 頁
WHEN SOMETHING GOES WRONG
遇到錯誤,先檢查這裡
編譯器找不到 Main 或出現非法字元
檢查檔名 Main.java、public class Main 是否一致,以及引號、分號、括號是否為半形。使用 UTF-8 儲存與編譯。
同樣的文字用 == 卻得到 false
== 看參考是否相同;比較文字內容要用 equals。不要依賴字串池的共用情況。
平均值少了小數或大數計算變成負數
確認除法兩邊的型別以及中間結果是否溢位,必要時先轉 double 或 long 再運算。
PAUSE AND TRY
先不要急著看別人的寫法
- 預測 9 / 2、9 / 2.0 與 (double)(9 / 2) 的結果。
- 將傳值範例最後改成 values[0] = 100,結果為何不同?
- 把 Scanner 第一行改成 18 Java;哪一步會讀取失敗?
先用紙筆預測,再改動範例中的數字或文字。結果與預期不同時,找出最早開始不同的那一步。
把這幾件事帶走
- 先確認宣告型別,再推導每一步運算的型別。
- String 內容用 equals,陣列索引先檢查長度。
- Java 一律傳值,參考副本仍可能共用同一物件。
FROM READING TO PRACTICE
用三道免費題,練習本章觀念
先做簡單題確認語法,再把幾個步驟組合起來。三題都來自本章主題的 Java 免費題庫,難度表示需要組合的基本概念。
教材來源與 Java 11 對照
本章依據《第二部分 01 Java 基礎語法.pdf》PDF 第 4–75 頁整理,將原有觀念重新編寫為可閱讀與執行的網站教學。頁碼為 PDF 檔案頁次;舊版語法說明與已知誤植依 Java 11 修正,補充內容另有標示。
需要查閱更完整的規則時,可參考以下官方文件。