Go 指针 vs Java 引用:Java 开发者必读

内容分享2小时前发布
0 0 0

许多 Java 开发者在学习 Go 时,第一次看到 * 和 &,都会本能地紧张:

“Go 也要像 C 一样玩指针了吗?”

答案是:是指针,但和你想象的不一样。
本文将从 Java 开发者最熟悉的“引用”出发,帮你彻底搞清楚 Go 指针 vs Java 引用的本质差异


一、Java 引用:你“用过”,但从没真正见过

在 Java 中:

User u = new User("Tom");
  • u 是一个 引用
  • 实际对象在 堆内存
  • 引用本身不能运算
  • 不能拿到真实内存地址
u = null; // 只能断开引用

Java 的原则:

开发者永远不直接接触内存地址


二、Go 指针:可见、可控、但很克制

在 Go 中:

type User struct {
    Name string
}

u := User{Name: "Tom"}
p := &u
  • u 是一个值
  • p 是 u 的指针
  • & 取地址
  • * 解引用
fmt.Println(p)   // 内存地址
fmt.Println(*p)  // 实际值

Go 的态度:

允许你接触指针,但只在“安全范围内”


三、核心差异一览(先看结论)

维度

Java 引用

Go 指针

是否暴露地址

是否可运算

❌(禁止指针运算)

是否必需

隐式

显式

是否安全

高(受限)

空值

null

nil


四、参数传递:Java 最容易误解的点

Java:永远是值传递

void change(User u) {
    u = new User("Jack");
}

❗ 不会影响外部对象

但:

void changeName(User u) {
    u.name = "Jack";
}

✔ 会影响对象内部状态

由于 拷贝的是“引用的值”


Go:值 or 指针,一眼就能看出来

func change(u User) {
    u.Name = "Jack"
}

❌ 不会影响原值

func change(u *User) {
    u.Name = "Jack"
}

✔ 会影响原值

Go 的好处:

是否修改原值,写在函数签名里


五、结构体方法:Java 类方法 vs Go 接收者

Java

class User {
    String name;
    void setName(String n) {
        this.name = n;
    }
}

Go(值接收者)

func (u User) SetName(n string) {
    u.Name = n
}

❌ 不会修改原对象

Go(指针接收者)

func (u *User) SetName(n string) {
    u.Name = n
}

✔ 会修改原对象
这是 Go 项目中最常见的写法


六、Java 开发者最关心的问题

❓ Go 会不会像 C 一样容易内存泄漏?

❌ 不会

  • Go 有 GC
  • 无指针算术
  • 无手动释放内存

Go 指针 ≠ C 指针


❓ 那为什么 Go 还要指针?

三个核心缘由:

1️⃣ 避免大对象拷贝(性能)
2️⃣ 明确表达“我要修改你”
3️⃣ 实现接口和方法共享状态


七、什么时候该用 Go 指针?

✅ 推荐使用指针的场景

  • 需要修改结构体内容
  • 结构体较大
  • 方法接收者
  • 状态型对象(Service、Manager)

❌ 不推荐

  • 基本类型(int、bool)
  • 只读参数
  • 临时值

八、一句话总结(送你一句爆款)

Java 用“看不见的引用”保护你,
Go 用“受限的指针”信任你。

© 版权声明

相关文章

暂无评论

none
暂无评论...