在《深入理解JVM》中有这样一句话:“java通过引用类型操作堆上的具体对象,....,对象访问方式由虚拟机实现而定,主流的访问方式主要有使用句柄和直接指针两种.......”


那么引用,句柄,指针分别是什么?

句柄定义:    是 一些表的索引,是指针的指针,是由系统管理的引用标识,该标识可以被系统重新定位到一个内存地址上。是一个数字,一般和当前系统下的整数的位数一样。这个数字是一个对象的唯一标示,和对象一一对应。

句柄作用:在C语言环境下代替C++对象指针来用的。这种间接访问对象的模式增强了系统对引用对象的控制。

创建句柄就是构造,销毁句柄就是析构,用句柄调用函数相当于传入this指针。

指针定义:是引用对象的内存地址。

引用:对象的别名,实质就是功能受限但是安全性更高的指针。共享另一个变量的内存空间,

 

指针和句柄的区别:

windows内存管理器经常在内存中来回移动对象,一次啊来满足应用程序的内存需要,对象被移动意味着它的地址变化了。windows内存管理器移动对象在内存中的位置后,把对象的新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。

这个地址是在对象装载时有系统分配的,当系统卸载时又释放给系统。

句柄地址(稳定)——>记载着对象在内存中的地址——>对象在内存中的地址(不稳定)---->实际对象

程序每次重新启动,系统不保证分配这个程序的句柄还是原来那个句柄。

隐喻:

牧童遥指杏花村:牧童的手为指针,杏花村的牌子为句柄,杏花村为对象实例。

指针的实质是某个变量或者对象所在地址的首地址,是指向对象的;句柄是资源在创建过程中由windows赋予的,是代表这个资源的。

例如,杏花村可以搬家(实际上程序运行过程中,资源在内存中的地址是变化的),那么牧童的手的指向也就不同(指针)了,然而即使搬了家,“杏花村”这块牌匾是不变的,通过打听“杏花村”这个名称,还是可以间接找到它的(地址)