为什么 Java / Kotlin 从不说“句柄”,但你每天都在用句柄?
写了多年 Java / Kotlin,我们每天都在写:
A a = new A()、var b = B()但你有没有认真想过:
👉 a / b 到底是什么?
👉 new 到底创建了什么?
👉 “句柄”这个词,为什么在系统开发中总是出现?
本文试图从语言层 → 虚拟机层 → 系统层,一次把“句柄”这个概念讲清楚。
一、从最普通的一行代码开始
A a = new A();
或 Kotlin:
var b = B()
大多数人的理解是:
👉 a 是对象
👉 b 是对象
但这是使用层的说法,不是工程层的真相。
真正发生的是:
👉 对象创建在堆中
👉 变量中保存的是一个“可以定位对象的值”
也就是:
👉 new 创建的是对象,变量中保存的是对象的引用。
二、语言层:为什么我们只说“变量 / 引用”
在 Java / Kotlin 这样的高级语言中:
- 不能操作内存
- 不能算地址
- 不能释放对象
- 不能控制对象是否移动
所以语言规范刻意屏蔽底层细节,只给出一个概念:
👉 引用(reference)
你只能写:
变量 → 引用 → 对象
至于“引用怎么找到对象”,语言不关心。
三、虚拟机层:这是“对象引用机制”
从 JVM / ART 的角度看:
new A() 会:
- 在堆中分配内存
- 初始化对象
- 返回一个对象引用
这个“引用”,在实现上可能是:
- 直接指针
- 句柄表索引
- 压缩指针
- 其他间接结构
👉 实现可以不同,但目标只有一个:
让应用层“间接”访问对象。
四、系统层:这就是“句柄模型”
在系统架构中,这种模式有一个统一名字:
👉 句柄(Handle)模型
工程定义是:
句柄是一种由系统或运行时提供的“间接标识符”,
应用通过句柄访问对象或资源,而不能直接接触真实实体。
操作系统中最经典的例子:
int fd = open("a.txt");
fd 不是文件
fd 是文件在内核中的句柄
结构是:
fd → 内核表 → file 对象
而 Java 实际是:
a → JVM管理结构 → 堆对象
本质完全一致。
五、为什么现代系统一定要用句柄?
✅ 1. 隔离与安全
应用不能直接碰对象内存,系统可以做安全保护。
✅ 2. 可移动与重建
GC 可以移动对象
内核可以重建资源
句柄不变,只改映射。
✅ 3. 生命周期统一管理
对象什么时候创建
什么时候回收
什么时候失效
全部由系统托管。
六、统一认知模型(非常重要)
你可以把所有句柄统一成一个模型:
你 → 句柄(handle) → 管理层(table/runtime) → 真实对象
所以:
- Java/Kotlin 引用
- fd
- Binder handle
- textureId
- Surface
- native 封装对象
👉 从系统视角看,本质都是句柄模型。
七、一个工程师该如何“正确表述”
❌ a 就是对象
✅ a 是对象引用
🔥 a 在系统模型上属于句柄机制
比较标准的说法是:
在 Java/Kotlin 语言层我们称之为“引用变量”,
但从虚拟机和系统架构角度看,它本质是一种句柄机制。
八、从语言到系统的统一视角
当你真正理解句柄之后,会发现:
- Android Binder 传的是句柄
- Flutter Engine 暴露的是句柄
- OpenGL / Audio / Camera 用的是句柄
- JVM / ART 管的是句柄
👉 现代系统几乎从不把“对象”直接交给应用,只交“访问权”。
九、总结一句话
👉 new 创建的是对象,变量中保存的是对象的句柄(引用)。
👉 Java/Kotlin 不说句柄,是因为句柄思想已经成为语言底座。
👉 句柄不是语法,而是现代系统最核心的设计模型之一。
更多推荐

所有评论(0)