雖同屬 C 系語言,但 Java 與 C++ 在記憶體模型、物件語意、資源管理上有本質差異。本文從 9 大維度系統對照,助 C++ 開發者快速建立 Java 思維模型,亦可作為雙向查閱手冊。
1. 資料型別與變數
| 特性 | C++ | Java |
| 基本型別大小 | 機器相關(16位系統 int=2 bytes) | 跨平台固定(int=4 bytes) |
| 無號型別 | 支援 unsigned | 無(char 為無號 16 位) |
| 布林型別 | bool | boolean |
| 字串 | std::string 可變、ASCII | String 不可變、UTF-16 |
| 字串比較 | 運算子 ==/< 直接比較 | equals()/compareTo() |
| 字串連接 | 僅限字串間 + | 任意物件 + 自動 toString() |
2. 變數初始化與常數
- C++ **區域變數不自動初始化** → 含隨機垃圾值,**極易產生 Bug**
- Java 強制明確初始化(編譯器檢查),基本型別有預設值
- C++ 常數:
const int MAX = 100;(可在函式/類別外定義)
- Java 常數:
static final int MAX = 100;(必須在類別內)
- C++ 全域變數易濫用 → 難管理,**建議避免**;Java 無全域變數
3. 類別定義語法
// C++: 宣告與實作分離,以 :: 區分
class Point {
public:
Point(); Point(double x, double y);
void move(double dx, double dy);
double getX() const; // const 承諾不修改物件
private:
double x, y;
};
Point::Point() : x(0), y(0) {}
void Point::move(double dx, double dy) { x += dx; y += dy; }
double Point::getX() const { return x; }
// Java: 合併宣告實作,無 const,以 final 修飾不可變參考
public class Point {
private double x, y;
public Point() { this(0,0); }
public Point(double x, double y) { this.x=x; this.y=y; }
public void move(double dx, double dy) { x+=dx; y+=dy; }
public double getX() { return x; }
}
C++ 類別結尾需分號;Java 不需。
4. 物件語意:值 vs 參考 —— 核心分水嶺
| 操作 | C++ | Java |
| 建立物件 | Point p(1,2);(棧上直接構造) | Point p = new Point(1,2);(堆上 + 參考) |
| 預設構造 | Time now; 直接構造 | Time now = null; 僅參考 |
| 指派/傳參 | 深拷貝(複製實際值) | 淺拷貝(複製參考) |
| 修改副本影響原物件 | 否 | 是 |
| 多態變數 | 需指標 Base* p = new Derived() | 天然支援 Base p = new Derived() |
| 可為 null | 需指標 | 所有物件參考可為 null |
C++ 物件變數即**值本身**,Java 物件變數是**參考(安全指標)**。
5. 函式/方法參數傳遞
- Java:**唯一**按值傳遞(參考值),但可透過參考修改物件內容
- C++:雙模式
- Call by Value(預設):拷貝值/參考值
- Call by Reference:
void swap(int& a, int& b) 直接操作原變數
- C++ 交換函式經典實作:
void swap(int& a, int& b) —— Java 無法直接實現
6. 向量/容器
// C++ vector: 兼具陣列隨機存取 + 動態擴容
vector<int> v; v.push_back(10); v.pop_back();
for (int i=0; i
Java ArrayList 參考語意,指派僅複製參考。
7. I/O 流
// C++: iostream, 運算子重載
cout << "Hello " << x << "\n";
cin >> x >> fname;
getline(cin, line);
if (cin.fail()) cerr << "Bad input";
// Java: System.out/in, 格式化 API
System.out.printf("Hello %d%n", x);
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
String line = sc.nextLine();
8. 指標 vs 參考 vs 記憶體管理
| 特性 | C++ 指標 | Java 參考 |
| 語法 | T* p = new T(); *p, p->method() | T p = new T(); p.method() |
| 算術運算 | 支援 p++ | 不支援 |
| 取位址 | &obj | 不可 |
| 空值 | NULL/nullptr | null |
| 解構/刪除 | 手動 delete p; → 記憶體洩漏/懸空指標風險 | GC 自動回收,不可干預 |
| 安全性 | 無運行期檢查,錯誤導致崩潰 | 空指標拋出 NPE,型別安全 |
C++ **RAII**(Resource Acquisition Is Initialization)配合智慧指標 unique_ptr/shared_ptr 為現代最佳實踐;Java 完全委託 GC。
9. 繼承與多態
// C++: virtual 關鍵字啟用動態綁定
class Manager : public Employee {
public:
Manager(string name, double salary, string dept);
virtual void print() const; // 虛函式
private:
string department;
};
// 建構子呼叫父類:初始化列表
Manager::Manager(string n, double s, string d) : Employee(n, s) {
department = d;
}
// 父類方法呼叫:類名::
void Manager::print() const {
Employee::print();
cout << department << "\n";
}
// 多態:必須用指標/參考
vector<Employee*> staff;
staff.push_back(new Manager(...));
for (auto p : staff) p->print(); // 動態綁定
Java 所有非 static/private/final 方法預設虛擬(動態綁定),無需關鍵字。
遷移核心心法
- 值語意 → 參考語意:習慣
new、參考傳遞、GC
- 手動記憶體 → 自動 GC:專注業務邏輯,避免
finalize()
- 多重繼承 → 介面實作:
implements A, B
- const 正確性 → final + 不變物件設計
- 模板 → 泛型(型別擦除):運行期無型別參數
- 運算子重載 → 方法命名:
add()、equals()
理解本質差異,避免「用 Java 寫 C++」或「用 C++ 寫 Java」,才能在各自生態寫出地道、高效、安全的代碼。
- 上一篇文章: Tomcat 壓力測試實戰:acceptCount 參數調優解決連線失敗
- 下一篇文章: Hibernate 面試題精選匯總:從查詢優化到主鍵生成策略
Copyright ©
程式碼之家 All Rights Reserved