透過對比 Java 與 C++ 實作簡易堆疊,可深入理解兩種語言在記憶體管理、泛型與物件導向設計上的異同。本文提供完整原始碼與單元測試範例。
package org;
public class Stack {
// 內部節點類別
public static class Link {
protected Object data;
protected Link next;
public Link(Object data, Link next) {
this.data = data;
this.next = next;
}
}
private Link head = null;
public void push(Object data) {
head = new Link(data, head);
}
public Object peek() {
return head != null ? head.data : null;
}
public Object pop() {
if (head == null) return null;
Object obj = head.data;
head = head.next;
return obj;
}
}
package org;
import junit.framework.TestCase;
public class StackTest extends TestCase {
public void testStringStack() {
Stack s = new Stack();
assertEquals(null, s.pop());
s.push("a");
s.push("b");
assertEquals("b", s.peek());
assertEquals("b", s.pop());
assertEquals("a", s.pop());
assertEquals(null, s.pop());
}
public void testIntegerStack() {
Stack s = new Stack();
assertEquals(null, s.pop());
s.push(new Integer(1));
s.push(new Integer(2));
assertEquals(2, ((Integer)s.peek()).intValue());
assertEquals(2, ((Integer)s.pop()).intValue());
assertEquals(1, ((Integer)s.pop()).intValue());
assertEquals(null, s.pop());
}
}
Java 版本利用物件參考與自動垃圾回收,程式碼簡潔且型別安全(配合泛型更佳)。
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class Stack {
struct Link {
Link* next;
void* data;
Link(void* dat, Link* nxt) : data(dat), next(nxt) {}
}* head;
public:
Stack() : head(0) {}
void push(void* data) { head = new Link(data, head); }
void* pop() {
if (head == 0) return 0;
void* obj = head->data;
Link* old = head;
head = old->next;
delete old; // 手動釋放節點記憶體
return obj;
}
void* peek() { return head ? head->data : 0; }
};
int main() {
ifstream in("Stack.cpp");
Stack text;
string line;
while (getline(in, line)) {
text.push(new string(line)); // 動態配置字串物件
}
string* s;
while ((s = (string*)text.pop()) != 0) {
cout << *s << endl;
delete s; // 必須手動刪除字串物件
}
return 0;
}
C++ 版本需開發者自行管理記憶體(new/delete),使用 void* 達成泛型效果,但失去編譯期型別檢查,較易發生錯誤。
| 特性 | Java | C++ |
|---|---|---|
| 記憶體管理 | 自動 GC | 手動 new/delete |
| 型別安全 | Object 參考,可配合泛型 | void* 需強制轉型 |
| 例外處理 | 內建 try-catch | 可選,傳統用回傳值 |
| 標準庫支援 | java.util.Stack 現成可用 | std::stack 模板類別 |
教學建議:初學者可先掌握 Java 版本理解堆疊邏輯,再挑戰 C++ 版本體驗底層記憶體控制。