首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 流程控制與運算符進階教學

     編輯:Java 相關知識

Java 流程控制與運算符:從入門到精通

流程控制與運算符是程式邏輯的骨架。本文系統整理 Java 所有控制結構、運算符優先級、型別轉換規則,並提供實戰範例與常見陷阱。


一、流程控制結構完整圖譜

1. 選擇結構

// if-else 鏈
if (score >= 90) grade = 'A';
else if (score >= 80) grade = 'B';
else if (score >= 70) grade = 'C';
else grade = 'D';

// switch-case (Java 12+ 表達式寫法)
String dayName = switch (day) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "週末";
    default -> throw new IllegalStateException("無效日期: " + day);
};

// switch 傳統語句 (穿透特性)
switch (month) {
    case 12: case 1: case 2: season = "冬季"; break;
    case 3: case 4: case 5: season = "春季"; break;
    // ...
}

2. 迴圈結構

// for 迴圈 (三段式)
for (int i = 0; i < 10; i++) { ... }

// 增強 for (for-each) - 僅讀遍歷
for (String item : list) { ... }

// while - 先判斷
while (condition) { ... }

// do-while - 至少執行一次
do { ... } while (condition);

// 標籤配合 break/continue 控制外層迴圈
outer: for (int i = 0; i < 3; i++) {
    inner: for (int j = 0; j < 3; j++) {
        if (j == 1) break outer; // 跳出外層
    }
}

3. 異常控制流

try (Resource r = new Resource()) {  // try-with-resources 自動關閉
    riskyOperation();
} catch (SpecificException e) {
    handleSpecific(e);
} catch (Exception e) {
    handleGeneral(e);
} finally {
    cleanup(); // 無 try-with-resources 時必要
}

二、運算符深度解析

算術運算符陷阱

陷阱錯誤代碼正確做法
整數除法截斷int r = 5 / 2; // 2double r = 5.0 / 2; // 2.5
溢位int x = 2_000_000_000; x * 2 → 負數long x = 2_000_000_000L; 或 Math.multiplyExact()
浮點精度0.1 + 0.2 == 0.3 → falseBigDecimal 或誤差範圍比較
自增副作用int a=1; int b = a++ + ++a; // 混亂拆分語句,避免單表達式多次修改同變數

位元運算實戰技巧

// 權限掩碼
int READ = 1 << 0;   // 0001 = 1
int WRITE = 1 << 1;  // 0010 = 2
int EXEC = 1 << 2;   // 0100 = 4

int permission = READ | WRITE; // 0011 = 3
boolean canRead = (permission & READ) != 0;
permission |= EXEC;            // 新增執行權限
permission &= ~WRITE;          // 移除寫入權限

// 快速乘除 2 的冪次
int n = 10;
n << 3;  // n * 8 = 80
n >> 2;  // n / 4 = 2

// 判斷奇偶
(n & 1) == 1  // 奇數
(n & 1) == 0  // 偶數

// 交換兩數 (無需暫存變數)
a ^= b; b ^= a; a ^= b;

instanceof 模式匹配 (Java 16+)

// 傳統寫法
if (obj instanceof String) {
    String s = (String) obj; // 需要強轉
    System.out.println(s.length());
}

// Java 16+ 模式匹配:直接宣告並轉型
if (obj instanceof String s) {
    System.out.println(s.length()); // s 直接可用
}

// 在 switch 中使用 (Java 17+)
String formatted = switch (obj) {
    case Integer i -> "整數: " + i;
    case String s -> "字串: " + s;
    case null -> "空值";
    default -> "其他: " + obj.getClass().getSimpleName();
};

三元運算符型別推導規則

// 規則:若第二、三操作數型別不同,按數值提升規則推導共同型別
// 基本型別:提升至較大型別 (int + double → double)
// 參考型別:尋找共同父類/介面
// 一邊是 null:型別為另一邊

Integer a = 10;
Double b = 20.0;
Number result = true ? a : b; // Number (共同父類)

String s = true ? "hello" : null; // String
// String s = true ? null : "hello"; // 也是 String

三、輸入輸出與格式化

Scanner 進階用法

Scanner sc = new Scanner(System.in);

// 讀整行 (含空白)
String line = sc.nextLine();

// 正則分隔符
sc.useDelimiter("\\s*,\\s*"); // 以逗號分隔,忽略前後空白
while (sc.hasNext()) {
    String token = sc.next();
}

// 輸入驗證
if (sc.hasNextInt()) {
    int num = sc.nextInt();
} else {
    String garbage = sc.next(); // 消耗無效輸入
}

printf 格式化完整指南

格式說明範例輸出
%d十進位整數42
%05d補零寬度 500042
%f浮點數 (預設 6 位小數)3.141593
%.2f保留 2 位小數3.14
%s字串Hello
%-10s左對齊寬度 10Hello
%c字元A
%b布林true
%n平台換行符\n 或 \r\n
%tF日期 (yyyy-MM-dd)2024-01-15
%tT時間 (HH:mm:ss)14:30:00
System.out.printf("姓名: %-10s 年齡: %3d 分數: %6.2f%%%n", "張三", 18, 98.5);
// 輸出: 姓名: 張三      年齡:  18 分數:  98.50%

四、綜合實戰:簡易計算機

import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("簡易計算機 (輸入 q 退出)");
        
        while (true) {
            System.out.print("\n運算式 (如: 3 + 5): ");
            String line = sc.nextLine().trim();
            if ("q".equalsIgnoreCase(line)) break;
            
            try {
                String[] parts = line.split("\\s+");
                if (parts.length != 3) throw new IllegalArgumentException("格式錯誤");
                
                double a = Double.parseDouble(parts[0]);
                String op = parts[1];
                double b = Double.parseDouble(parts[2]);
                
                double result = switch (op) {
                    case "+" -> a + b;
                    case "-" -> a - b;
                    case "*" -> a * b;
                    case "/" -> {
                        if (b == 0) throw new ArithmeticException("除數不能為零");
                        yield a / b;
                    }
                    case "%" -> a % b;
                    default -> throw new IllegalArgumentException("不支援運算子: " + op);
                };
                
                System.out.printf("結果: %.2f %s %.2f = %.4f%n", a, op, b, result);
                
            } catch (Exception e) {
                System.out.println("錯誤: " + e.getMessage());
            }
        }
        System.out.println("再見!");
    }
}

五、最佳實踐清單

✅ 推薦做法

  • 迴圈變數限制在迴圈內宣告 (for (int i...))
  • 優先使用增強 for 遍歷集合/陣列
  • switch 表達式 (Java 12+) 取代傳統語句
  • 複雜條件提取為具名 boolean 變數/方法
  • 浮點比較使用 Math.abs(a-b) < EPSILON
  • 字串比較用 Objects.equals(a, b) 避免 NPE

❌ 避免做法

  • 在單一表達式中多次修改同一變數 (a = b++ + ++b)
  • 用 == 比較字串、包裝類、浮點數
  • 巨大的 if-else 鏈 (考慮策略模式、Map 查找、多態)
  • 空的 catch 區塊 (至少記錄日誌)
  • 在 finally 中 return/throw (會吞沒 try/catch 的異常)

扎實掌握流程控制與運算符,是寫出正確、高效、可維護 Java 代碼的基石。建議將運算符優先級表、格式化參考表列印貼在工位,遇到疑問隨時查閱,久而久之自然內化為直覺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved