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

Java main() 方法深度解析:JVM 啟動流程、參數傳遞與進階技巧

     編輯:Java 相關知識

標準簽名與規範

public static void main(String[] args)
  • public:JVM 需公開存取入口。
  • static:JVM 無需實例化類別即可呼叫。
  • void:無回傳值;結束狀態碼用 `System.exit(code)`。
  • String[] args:命令列參數陣列 (不含類別名),空白分隔,支援引號包含空白。

JVM 啟動與 main 執行流程

  1. 載入啟動類別 (Bootstrap ClassLoader)。
  2. 連結:驗證、準備 (靜態欄位賦預設值)、解析 (符號參考→直接參考)。
  3. 初始化:執行 `()` — 靜態變數賦值、靜態區塊 (`static {}`)。
  4. 呼叫 `main(String[])`。
  5. `main` 返回 → 執行緒結束 → 若無非守護執行緒,JVM 關閉。

靜態區塊先於 main 執行


public class Demo {
    static {
        System.out.println("1. 靜態區塊"); // 最先印出
    }
    public static void main(String[] args) {
        System.out.println("3. main 方法");
    }
    {
        System.out.println("2. 實例區塊"); // 不會執行,因未 new 物件
    }
}

命令列參數處理


public class ArgsDemo {
    public static void main(String[] args) {
        System.out.println("參數個數: " + args.length);
        for (int i = 0; i < args.length; i++) {
            System.out.printf("args[%d] = %s%n", i, args[i]);
        }
        
        // Java 8+ Stream 處理
        Arrays.stream(args).forEach(System.out::println);
    }
}

執行:`java ArgsDemo hello "world java" 123`


參數個數: 3
args[0] = hello
args[1] = world java
args[2] = 123

進階技巧與陷阱

1. 多 main 方法類別

單一 JAR 可包含多個含 `main` 的類別,透過 `java -cp app.jar com.example.ClassA` 指定啟動類。`MANIFEST.MF` 的 `Main-Class` 決定 `java -jar` 行為。

2. 參數解析庫

複雜 CLI 請使用 Picocli、Apache Commons CLI 或 Spring Shell,支援子命令、型別轉換、自動生成幫助。

3. 模組系統 (Java 9+)


// module-info.java
module com.example.app {
    requires java.logging;
    // main 類別不需在 module-info 宣告
}

執行:`java --module-path mods -m com.example.app/com.example.Main`

4. 避免在 main 做太多事


// 反模式:main 巨大、難測試
public static void main(String[] args) { /* 500 行業務邏輯 */ }

// 正規模式:main 僅啟動器
public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(App.class, args);
    // 或手動組裝
    MyService service = new MyServiceImpl(new DbRepo());
    service.start(args);
}

5. JVM 參數 vs 應用參數


java -Xms256m -Xmx1g -Denv=prod -jar app.jar --server.port=8080 --db.url=jdbc:mysql://...
       ↑ JVM 參數          ↑ 應用參數 (main args / Spring Boot properties)

常見面試題

  1. main 可否被覆寫? 不能,`static` 方法屬於類別,不參與多態。
  2. main 可否拋出例外? 可宣告 `throws Exception`,JVM 會印堆疊追蹤並非零碼退出。
  3. 能否在 main 中呼叫另一個 main? 能,`AnotherClass.main(new String[]{"arg1"})`,但屬同一 JVM 進程。
  4. args 為 null 可能嗎? 不可能,JVM 保證至少為空陣列 `new String[0]`。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved