C# 與 Java 同屬強型別、物件導向、執行於受控環境 (CLR / JVM) 的語言,語法高度相似,但在設計哲學、生態系統與語言特性上有關鍵差異。本文從關鍵字、型別系統、泛型、委派/事件、非同步、執行階段等維度深度比較。
1. 基礎結構與關鍵字對照
| 概念 | C# | Java |
| 命名空間/套件 | namespace | package |
| 引用套件 | using | import |
| 主程式進入點 | static void Main(string[] args) (大寫 M,4 種多載) | public static void main(String[] args) (小寫 m,單一簽章) |
| 標準輸出 | Console.WriteLine() | System.out.println() |
| 標準輸入 | Console.ReadLine() | Scanner.nextLine() |
| 類別檔案命名 | 類別名與檔名可不同 | public 類別名必須與檔名相同 |
2. 型別系統核心差異
值型別 vs 參考型別
- C#:明確區分
struct (值型別,存放於堆疊/內嵌) 與 class (參考型別,存放於堆積)。支援使用者自訂值型別,int、bool 等皆為結構體別名。
- Java:僅有基本型別 不是物件,其餘皆為參考型別。Java 10+ 引入
var、Value Types (Valhalla 專案進行中) 但尚未普及。
封箱/拆箱
- C#:值型別轉為
object/介面時發生**封箱** (配置堆積記憶體、複製值),拆箱需強制轉型。頻繁封箱影響效能,可用泛型避免。
- Java:基本型別自動封箱為對應包裝類別 (
int → Integer),語法透明但同樣有效能成本。
3. 泛型實作機制
| 特性 | C# (Reified Generics) | Java (Type Erasure) |
| 執行期型別資訊 | 保留完整型別參數 (List<int> ≠ List<string>) | 編譯後抹除為原始型別 (List<Integer> → List) |
| 值型別支援 | 原生支援 List<int> 無封箱 | 只能用包裝類別 List<Integer> 有封箱 |
| 執行期建立泛型 | typeof(T), new T() (需 where T:new()) | 不可直接 new T(),需工廠或反射 |
| 共變/逆變 | in/out 關鍵字 (介面/委派) | ? extends/? super (使用點宣告) |
4. 委派、事件與 Lambda
- C#:
delegate 是一級型別,支援多播、非同步呼叫 (BeginInvoke)、event 關鍵字語言層級支援訂閱/取消訂閱語法 (+=/-=)。
- Java:無委派概念,使用單一方法介面 (Functional Interface) + Lambda 表達式 (
Runnable, Consumer<T> 等)。事件模式需手動實作觀察者模式 (如 PropertyChangeSupport)。
5. 非同步程式設計
| 模式 | C# | Java |
| 核心抽象 | Task/Task<T> (承諾模型) | CompletableFuture<T> / Future<T> |
| 語法糖 | async/await (編譯器狀態機) | 無語法糖,鏈式 thenApply/thenCompose 或虛擬執行緒 (Project Loom, Java 21+) |
| 取消機制 | CancellationToken 協作式取消 | Future.cancel(true) 中斷執行緒 |
6. 執行階段與生態
- 跨平台:.NET 6+ 全平台原生支援 (Windows/Linux/macOS, x64/ARM64);Java 自誕生即跨平台 (JVM)。
- 原生互操作:C#
DllImport/NativeAOT 極簡單;Java 需 JNI/JNA/Panama (進行中) 較繁瑣。
- 工具鏈:.NET CLI (
dotnet) 整合建置、測試、NuGet、Docker;Java 需 Maven/Gradle + 獨立 IDE。
- 語言演進速度:C# 每年大版本 (C# 12/13) 激進引入新特性 (Record, Pattern Matching, Primary Constructor);Java 6 個月釋出但 LTS 週期較長 (Java 8/11/17/21),企業採用較保守。
總結:如何選擇?
- 選 **C#**:Windows 桌面 (WPF/WinForms/MAUI)、Unity 遊戲開發、.NET 生態 (ASP.NET Core, EF Core, Blazor)、需高效能值型別/泛型/原生互操作、偏好現代語法糖。
- 選 **Java**:企業級伺服器端傳統強項 (Spring Boot, Jakarta EE)、Android 原生開發 (雖 Kotlin 為主)、超大型團隊長期維護、嚴格向後相容需求、JVM 生態工具 (監控、分析) 成熟。