[Java] 型別與語法
Java 的型別與對應變數宣告方式
| Type 類型 | 說明 | 變數宣告範例 | 常用/差異說明 |
|---|---|---|---|
| byte | 8-bit 整數 | byte b = 100; | 偏少用,通常用於大量資料節省記憶體 |
| short | 16-bit 整數 | short s = 1000; | 偏少用,通常用於節省記憶體 |
| int | 32-bit 整數 | int i = 100000; | 最常用整數型別,適合大部分情況 |
| long | 64-bit 整數 | long l = 100000000L; | 用於大整數或時間戳、金額等需大數範圍 |
| float | 32-bit 浮點數 | float f = 3.14f; | 偏少用,一般用 double 更精準 |
| double | 64-bit 浮點數 | double d = 3.14159265; | 最常用浮點型別,適合大部分計算 |
| char | 單一字元 | char c = 'A'; | 用於單字元或字元操作 |
| boolean | true / false | boolean flag = true; | 最常用布林型別 |
| String | 字串(參考型別) | String name = "Jeremy"; | 最常用文字型別,操作方便 |
| Array | 陣列(參考型別) | int[] arr1 = {1,2,3};int[] arr2 = new int[5]; | 儲存同型別多個元素,arr1 直接初始化,arr2 指定大小再賦值 |
| Object | 物件(參考型別,父類別) | Object obj = new Object(); | 所有類別父類別,可存任何物件,但需強制轉型 |
Object
Object 這個詞其實在 Java 理有兩種意思。上述表格的 Object 是一種型別的概念,代表 Java 中所有類別的父類別 (superclass)。
但在日常使用中,object 這個詞也常被用來泛指「物件」,意思是某個類別 (class) 的實例 (instance)。
所以要看上下文來判斷 object 是指哪一種意思:
- 廣義的
object:指的是任何類別 (class) 的實例 (instance),也就是說,當你使用new關鍵字創建一個類別的物件時,這個物件就是一個object。
例如:
Person person1 = new Person("Alice", 25);
String s = "Hello";
int[] arr = new int[5];
上述的 person1、s 和 arr 都是 object,因為它們分別是 Person、String 和 int[] 類別的實例。
- 狹義的
Object類別:指的是 Java 提供的Object類別,這是所有類別的父類別。
Object obj = new Person("Alice", 25);
雖然一樣是 Person 類別的實例,但因為宣告成 Object 型別,所以只能使用 Object 類別的方法,無法直接使用 Person 類別特有的方法,除非進行強制轉型 (casting)。
以口語一點來解釋就是:
- 廣義上的
object:桌上的咖啡杯,你很明確知道桌上的是咖啡杯這個物件。 - 狹義上的
Object:桌上的杯子,但你不知道它是咖啡杯還是茶杯,只知道它是個杯子這個類別。
提示
平常討論 Java 或 OOP 時,大家說的 object 通常都是廣義的意思,也就是「某個類別的實例」。
型別的 Object 通常都是在特定情況下才會討論。
迴圈
for 迴圈
範例 01
public class ShoppingCart {
public static void main(String[] args) {
double[] prices = {12.5, 9.9, 5.0, 20.0};
double total = 0;
// 計算購物車總價
for (int i = 0; i < prices.length; i++) {
total += prices[i];
}
System.out.println("購物車總價: $" + total);
}
}
範例 02
public class practiceSum {
public static void main(String[] args) {
NonStaticCaculate obj = new NonStaticCaculate();
obj.sum(1, 10, 1);
obj.sum(1, 99, 2);
obj.sum(4, 97, 3);
}
}
class NonStaticCaculate {
public void sum (int head, int tail, int diff) {
int total = 0;
for (int i = head; i <= tail; i += diff) {
total += i;
}
System.out.println("The sum of is: " + total);
}
}
while 迴圈
public class AccumulateExample {
public static void main(String[] args) {
int[] dailySteps = {1000, 2500, 3000, 2000, 1500};
int totalSteps = 0;
int day = 0;
// 累加每天步數,直到總步數超過 5000 步
while (totalSteps <= 5000) {
totalSteps += dailySteps[day];
System.out.println("第 " + (day + 1) + " 天步數: " + dailySteps[day] + ", 累計步數: " + totalSteps);
day++;
}
System.out.println("累計步數超過 5000,總共用了 " + day + " 天");
}
}
do-while 迴圈
import java.util.Scanner;
public class PasswordCheck {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String password;
// 使用者至少輸入一次
do {
System.out.print("請輸入密碼: ");
password = scanner.nextLine();
} while (!password.equals("1234"));
System.out.println("密碼正確,登入成功!");
scanner.close();
}
}
巢狀迴圈
for 巢狀迴圈印出九九乘法表
public class MultiplicationTable {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "x" + i + "=" + (i*j) + "\t");
}
System.out.println();
}
}
}
while 巢狀迴圈印出各班級學生分數
public class ClassScores {
public static void main(String[] args) {
int[][] scores = {
{85, 90, 78}, // 班級 1
{92, 88, 79}, // 班級 2
{75, 80, 85} // 班級 3
};
int classIndex = 0;
while (classIndex < scores.length) {
System.out.println("班級 " + (classIndex + 1) + " 成績:");
int studentIndex = 0;
while (studentIndex < scores[classIndex].length) {
System.out.println(" 學生 " + (studentIndex + 1) + ": " + scores[classIndex][studentIndex]);
studentIndex++;
}
classIndex++;
System.out.println();
}
}
}
條件判斷
if-else 條件判斷
int score = 85;
// if-else
if (score >= 90) {
System.out.println("Excellent!");
} else if (score >= 60) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
switch 條件判斷
public class UserRoleExample {
public static void main(String[] args) {
String role = "admin"; // 可能值: "admin", "editor", "viewer"
String permission;
switch (role) {
case "admin":
permission = "可以新增、編輯、刪除資料";
break;
case "editor":
permission = "可以編輯資料";
break;
case "viewer":
permission = "只能查看資料";
break;
default:
permission = "無權限";
}
System.out.println("身份: " + role + " → " + permission);
}
}
提示
break 是用來跳出 for、switch 或迴圈的語句;continue` 是用來跳過本次迴圈,直接進入下一次迴圈的語句。
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // 偶數跳過,直接進入下一次迴圈
}
System.out.println(i); // 只會印出奇數
}
method
無回傳值的 method 會以 void 宣告
void printMessage(String message) {
System.out.println(message);
}
有回傳值的 method 會以回傳型別宣告
int add(int a, int b) {
return a + b;
}
overloading (多載)
最早學 overloading 是在 TypeScript 裡面,但其實用 TS 學 overloading 會有點抽象,但從 Java 等 OOP 語言來看就會比較直觀。
那 overloading 其實具有幾個特性:
- method 名稱相同
- 參數數量、型別或順序不同
- 回傳型別的不同不能單獨作為判斷依據,必須配合參數差異 → 簡單說就是,兩個 method 不能只有回傳型別不同,其他都一樣,這樣會造成呼叫時無法判斷要用哪一個 method
範例 01
public class Calculator {
// 加法:兩個 int
int add(int a, int b) {
return a + b;
}
// 加法:三個 int
int add(int a, int b, int c) {
return a + b + c;
}
// 加法:兩個 double
double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3)); // 使用 int, int
System.out.println(calc.add(2, 3, 4)); // 使用 int, int, int
System.out.println(calc.add(2.5, 3.5)); // 使用 double, double
}
}
範例 02
public class overloadIssue {
public static void main(String[] args) {
int[][] intMatrix = {
{1, 2, 3, 4, 5},
{9, 8, 7, 6, 5}
};
double[][] doubleMatrix = {
{1.26, 2.25, 3.74, 4.26, 9.02},
{9.53, 9.99, 7.36, 6.2, 5.5}
};
int intResult = maxEle(intMatrix);
double doubleResult = maxEle(doubleMatrix);
System.out.println("int result of maxEle is: " + intResult);
System.out.println("double result of maxEle is: " + doubleResult);
}
static int maxEle (int x[][]) {
int max = x[0][0];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] > max) {
max = x[i][j];
}
}
}
return max;
}
static double maxEle (double x[][]) {
double max = x[0][0];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] > max) {
max = x[i][j];
}
}
}
return max;
}
}
一些範例
一個結合輸出入、條件判斷、迴圈、類別的例子
import java.util.Random;
import java.util.Scanner;
public class MockApiCall {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ApiCaller apiCaller = new ApiCaller();
System.out.println("請問是否呼叫 API?(y/n)");
String userInput = scanner.nextLine().trim().toLowerCase();
if (!userInput.equals("y")) {
System.out.println("使用者選擇不呼叫 API,程式結束。");
} else {
do {
boolean isSuccessful = apiCaller.callApi();
if (isSuccessful) {
break;
} else {
apiCaller.retryCount--;
if (apiCaller.retryCount > 0) {
System.out.println("API 呼叫失敗,剩餘重試次數:" + apiCaller.retryCount);
} else {
System.out.println("API 呼叫失敗,已無剩餘重試次數。");
}
}
} while (apiCaller.retryCount > 0);
}
scanner.close();
}
}
class ApiCaller {
Random random = new Random();
int retryCount = 5;
public boolean callApi() {
boolean mockIsApiSuccessful = random.nextInt(100) < 10;
if (mockIsApiSuccessful) {
System.out.println("API call successful.");
return true;
} else {
System.out.println("API call failed.");
return false;
}
}
}
將使用者輸入的字串中的數字加總
題目需求為,當使用者輸入如:「abc 12 de 5」時,程式能夠計算出 12 和 5 的總和 17。
import java.util.Scanner;
public class SumNumbersInString {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入一串字串(可包含數字):");
int sum = 0;
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
sum += scanner.nextInt(); // 讀到數字就加總
} else {
scanner.next(); // 不是數字就跳過
}
}
System.out.println("字串中的數字總和為: " + sum);
scanner.close();
}
}