Java的指针和C语言的有些区别
一、创建新节点 vs 创建指针
创建新节点:
ListNode newNode = new ListNode(5); // 创建一个真实的新节点对象
创建指针(引用):
ListNode ptr; // 只是声明一个引用变量,没有创建新对象
这两个不一样!
用例子对比
// 方式1:创建新节点
ListNode node1 = new ListNode(5);
// 内存中真的创建了一个节点对象,有 val=5,next=null
// 方式2:只声明引用
ListNode node2;
// 没有创建任何对象,node2 目前是空的(null)
// 如果你现在用 node2,会报错
// 方式3:让 node2 指向已存在的对象
node2 = node1;
// node2 现在指向 node1 指向的同一个对象
C 语言的对比
在 C 中更清楚:
// 创建新节点
struct Node* node1 = malloc(sizeof(struct Node)); // 分配内存,创建新对象
node1->val = 5;
// 只声明指针
struct Node* node2; // 指针变量声明了,但没有指向任何地址
// 让 node2 指向 node1
node2 = node1; // 两个指针指向同一块内存
Java 的简化
Java 用 new 关键字统一处理:
ListNode node = new ListNode(5); // new = 分配内存 + 创建对象
相当于 C 的:
struct Node* node = malloc(sizeof(struct Node));
node->val = 5;
回到之前的代码
ListNode preLeftNode = dummyHead;
// 这里没有 new,所以没有创建新节点
// 只是让 preLeftNode 指向 dummyHead 已存在的对象
ListNode dummyHead = new ListNode(0);
// 这里有 new,所以创建了一个新的节点对象
简单说:
-
new ListNode()= 创建新节点(真的在内存中创建对象) -
ListNode ptr = xxx= 创建指针/引用(指向已存在的对象)
二、引用类型 vs 原始类型
Java 有两种数据类型:
原始类型(基本类型):
int x = 5; // 直接存储值 5
double y = 3.14; // 直接存储值 3.14
boolean flag = true; // 直接存储值 true
引用类型:
ListNode node = new ListNode(5); // 存储的是对象的地址/引用
String s = "hello"; // 存储的是字符串对象的地址/引用
ArrayList list = new ArrayList(); // 存储的是对象的地址/引用
关键区别
| 原始类型 | 引用类型 |
|---|---|
| 直接存储值 | 存储对象的地址(引用) |
int x = 5; |
ListNode node = new ListNode(5); |
| 内存中直接是数字 5 | 内存中是地址,指向实际对象 |
图解理解
原始类型:
变量 x
┌─────┐
│ 5 │ ← 直接存储值
└─────┘
引用类型:
变量 node
┌──────────────┐ ┌──────────────┐
│ 地址:0x1234 │ ──────→ │ ListNode对象 │
└──────────────┘ │ val: 5 │
│ next: null │
└──────────────┘
用 C 语言类比
// 原始类型:直接存储值
int x = 5; // x 里面就是数字 5
// 引用类型:存储地址(指针)
struct Node* node = malloc(...); // node 里面存的是内存地址
为什么叫"引用"?
因为这个变量只是**引用(指向)**真实的对象,而不是直接包含对象本身。
ListNode node1 = new ListNode(5);
ListNode node2 = node1;
// node1 和 node2 都是引用,都指向同一个对象
// 修改这个对象,两个引用都能看到变化
node1.val = 10;
System.out.println(node2.val); // 输出 10
简单记住
引用类型 = 指向对象的变量
在你的链表代码中:
ListNode pre = null; // pre 是引用类型,现在是空引用(没指向任何对象)
ListNode cur = head; // cur 是引用类型,指向 head 对象
ListNode node = new ListNode(5); // node 是引用类型,指向新创建的对象
所有这些 ListNode 类型的变量都是引用类型。