跳至主要内容

[Java] 型別與語法

Java 的型別與對應變數宣告方式

Type 類型說明變數宣告範例常用/差異說明
byte8-bit 整數byte b = 100;偏少用,通常用於大量資料節省記憶體
short16-bit 整數short s = 1000;偏少用,通常用於節省記憶體
int32-bit 整數int i = 100000;最常用整數型別,適合大部分情況
long64-bit 整數long l = 100000000L;用於大整數或時間戳、金額等需大數範圍
float32-bit 浮點數float f = 3.14f;偏少用,一般用 double 更精準
double64-bit 浮點數double d = 3.14159265;最常用浮點型別,適合大部分計算
char單一字元char c = 'A';用於單字元或字元操作
booleantrue / falseboolean 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 是指哪一種意思:

  1. 廣義的 object:指的是任何類別 (class) 的實例 (instance),也就是說,當你使用 new 關鍵字創建一個類別的物件時,這個物件就是一個 object
    例如:
Person person1 = new Person("Alice", 25);
String s = "Hello";
int[] arr = new int[5];

上述的 person1sarr 都是 object,因為它們分別是 PersonStringint[] 類別的實例。

  1. 狹義的 Object 類別:指的是 Java 提供的 Object 類別,這是所有類別的父類別。
Object obj = new Person("Alice", 25);

雖然一樣是 Person 類別的實例,但因為宣告成 Object 型別,所以只能使用 Object 類別的方法,無法直接使用 Person 類別特有的方法,除非進行強制轉型 (casting)。
以口語一點來解釋就是:

  1. 廣義上的 object:桌上的咖啡杯,你很明確知道桌上的是咖啡杯這個物件。
  2. 狹義上的 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 是用來跳出 forswitch 或迴圈的語句;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 其實具有幾個特性:

  1. method 名稱相同
  2. 參數數量、型別或順序不同
  3. 回傳型別的不同不能單獨作為判斷依據,必須配合參數差異 → 簡單說就是,兩個 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();
}
}