Java句柄与指针(java中句柄)

createh52个月前 (01-24)技术教程25

ava中的句柄分为两种:

对象句柄
jvm中对象访问句柄

一、对象句柄

句柄:一个唯一的整数,作为对象的身份id,区分不同的对象,和同类中的不同实例。程序可以通过句柄访问对象的部分信息。句柄不代表对象的内存地址。在Java中的任何东西都可以看做对象,存在一种标识符实际指向一个对象的句柄.在Java的其他地方或者数据中也有称为 "引用"或者 "指针". 只是一个引用地址,我们不能认为Java中没有指针,其实这就是一个指针,我们每次操作对象就是根据句柄去找到对象操作对象的. 即使没有对象,我们也可以让句柄单独存在。

可以将句柄简单的理解为对象的引用.

举一个例子:
Vehicle ve = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。

右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。
末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。
左边的“Vehicle veh 1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。
"="操作符使对象引用指向刚创建的那个Vehicle对象。
我们可以把这条语句拆成两部分:
Vehicle ve;

ve = new Vehicle();

效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。

一个Vehicle类可以据此创建出无数个对象,这些对象不可能全叫“Vehicle”。对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。Java中就是用句柄来标识每一个对象的.

如何更好的理解句柄呢?我们再举一个例子:

Person person;

person = new Person("张三");

person = new Person("李四");

刚开始我们分配了一个句柄,它没有连接到任何对象,它就是null。在第二行,我们new了一个叫“张三”的person,将person指向“张三”这个对象,然后又指向了“李四”这个对象。也就是说,Person person,这句话只是声明了一个Person类的引用,它可以指向任何Person类的实例。


二、对象访问句柄

由于reference类型在Java虚拟机规范里只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到Java堆中的对象的具体位置,因此不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄和直接指针。

使用句柄访问方式
如果使用句柄访问方式,Java堆中会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。使用句柄方式最大的好处就是reference中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要被修改。


三、使用直接指针访问方式


如果使用该方式,Java堆对象的布局就必须考虑如何放置访问类型数据的相关信息,reference中直接存储的就是对象地址。使用直接指针方式最大的好处就是速度更快,他节省了一次指针定位的时间开销。

就HotSpot而言,他使用的是直接指针访问方式进行对象访问,但从整个软件开发的范围来看,各种语言和框架使用句柄来访问的情况也十分常见。

总结,在对象分配的时候,句柄使用较多.在对象访问的时候,其实是可以权衡的,如果使用直接指针的方式进行对象访问,那么更多的就是关注堆中已分配对象的快速访问;如果使用句柄访问的方式,更多的是考虑到GC的时候,对象的移动十分频繁(具体参照JVM垃圾回收算法),那么句柄访问方式会更有优势。所以目前来看,就HotSpot来说,对象分配更多使用句柄,对象访问使用直接指针。
想要学习更多JAVA知识的小伙伴看过来!

「链接」

相关文章

Java中标识符的命名规则(java中标识符的命名规则有哪些)

在 Java 编程中,标识符的命名有着明确且重要的规则。首先,标识符必须以字母、下划线(_)或美元符号($)开头,后续部分可以是字母、数字、下划线或美元符号的组合。这意味着标识符不能以数字开头,否则将...

Java中的关系运算符(java的关联关系)

5.1运算符的介绍运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等5.2算术运算符5.2.1介绍算术运算符是对数值类型的变量进行运算的。5.2.2算术运算符分类运算符运算范例结果+正号+55-...

「书讯」面向对象程序设计(Java)(面向对象程序设计教程)

《面向对象程序设计(Java)》作者:李建勋,郭建华,佟瑞 著出版日期:2021年4月开本:16开出版社:经济管理出版社小编推荐面向对象程序设计是一种接近人类思维活动的计算机软件程序设计思想,其具备...

第3天|Java入门有野,基础语法(java入门语句)

老铁,我是不会告诉你我的计算机上安装了Eclipse,用于开发Spring Boot;安装了Android Studio用于开发Android App;安装了DevEco-Studio用于试验鸿蒙Ap...

Java教程的基础语法大汇总(java基础语法总结)

一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它...

JAVA学习基础之简单JAVA 程序(java简单教程)

第二章、简单JAVA 程序一个简单的JAVA程序(文件名必须与程序中的主类名称一致)Test.java:public class Test{public static void main(String...