Java 句柄 引用

一. 在学习什么是句柄之前我们先学习虚拟机的对对象的访问方式

【1】句柄访问方式:

使用句柄访问对象,会在堆中开辟一块内存作为句柄池,句柄中储存了对象实例数据(属性值结构体)的内存地址,访问类型数据的内存地址(类信息,方法类型信息),对象实例数据一般也在heap中开辟,类型数据一般储存在方法区中。使用句柄访问的好处是句柄中储存的是稳定的对象地址,当对象被移动时候,只需要更新句柄中的对象实例部分的值即可,句柄本身不用被移动修改。 句柄方式访问

【2】指针访问方式: 
直接指针访问方式指reference中直接储存对象在heap中的内存地址,但对应的类型数据访问地址需要在实例中存储,使用直接指针的好处相对于句柄来讲,少了一次指针定位时间的开销,缺点是,当对象被移动时(如进行GC后的内存重新排列),对象的引用(reference)也需要同步更新。

指针访问方式

注意:sun公司的hotspot虚拟机使用的是第二种方式,在频繁的对象访问过程中,由于节省一次指针定位开销,积少成多后的性能提升影响非常可观。

二. 什么是句柄

  句柄(Handle)来标示应用程序中不同的对象和同类中不同的实例
  注意:句柄有人认为是指针、或者引用

下面就是一个简单的句柄(不怎么形象)

    class demo{
        @Test
        public void test(){
            String s;//句柄
            String s1=new String();句柄=实例对象
            s1 = "a";//通过句柄操作对象
            System.out.println(s1);
            System.out.println(s1.hashCode());
        }
    }

句柄最简单的例子就是,把句柄看作一个遥控器(鼠标),而对象看作电视机(电脑),你可以通过遥控器的发出的频率来控制电视显示的节目(通过鼠标控制电脑的软件,来达到自己的自定义界面)可以把String s;看成创建句柄(遥控器),而 new String() 看成对象(电视)而中间的‘=’号,你可以看成连接介质.

方法运行解析

三. 区分什么是指针/引用/句柄

1.指针是对象在内存中的地址; 
2.引用是对象的别名,其实质就是功能受限但是安全性更高的指针; 
3.句柄是指针的指针,句柄实际上是一个数据,是一个Long (整长型)的数据。句柄是一个标识符,是拿来标识对象或者项目的

 

 

首先要分清是在什么地方讨论,在以前学C时,是这么区分的(1)指针是对象在内存中的地址;(2)引用是对象的别名,其实质就是功能受限但是安全性更高的指针;(3)句柄是指针的指针,句柄实际上是一个数据,是一个Long (整长型)的数据。句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样。Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。

然后我们回到JAVA来解释这个问题:

Java中有3个数据类型:基本数据类型、引用类型和null类型。其中,引用类型包括类类型(含数组)、接口类型。为了区别引用类型的变量标识符和基本数据类型变量标识符,我们特别的(特意的)使用Handle来称呼引用类型的变量标识符。对象的引用是创建对象时的返回值!引用是new表达式的返回值。new A(); 这里真正创建了一个对象,但我们没有用句柄去持有(hold、拿着、保存)该引用。handle是变量,reference是一种变量值。


A a = new A() ;

(1)句柄a:常见为A a;或A a=new A();前者没有被初始化,后者被手工初始化。(如果a是一个类的成员变量,会被默认初始化。)句柄不同于基本变量的关键,它是一种间接寻址方式。句柄声明常常称为对象声明(如果你感到可能引起混淆,不理睬对象声明的说法好啦)。
 

(2)创建对象:new A(); 这才是真正的创建对象。对象一般通过new表达式来创建。

(3)计算new表达式的值:计算new表达式的值的整个过程,在微观上完成了对象的创建和这个对象自己的成员变量的初始化,在宏观上得到new表达式的值,这个值称为新对象的引用;

(4)引用:new A()的值。引用可以简单的看作对象占据内存空间的地址;通过对象的引用,就可以方便的与其他对象区别开来,引用就是对象独特的身份标识。

(5)句柄的初始化:句柄 = 引用;即把引用赋值给句柄,如语句a=new A();完成句柄的初始化后,就可以用句柄遥控对象了。

(6)对于语句A a=new A();是对象创建及对象初始化与句柄的初始化的合并。

 

参考:

https://blog.csdn.net/lly983909814/article/details/72529773

http://www.cnblogs.com/lsjwzh/archive/2010/05/08/1730480.html

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值