如何在Java中获取类对象的引用值?

时间:2016-01-05 11:25:22

标签: java memory memory-management

public class Box {

    int height;
    int length;
    int width;

}



public class Volume {

    public static void main(String args[]){

        Box mybox = new Box();
        Box mybox1= mybox;
        Box mybox2 = new Box();


        System.out.println(" The address of the mybox object is:"+System.identityHashCode(mybox));
        System.out.println(" The value of the mybox object is:"+mybox);

        System.out.println(" The address of the object mybox1 is :"+ System.identityHashCode(mybox1));
        System.out.println(" The value of the mybox1 object is:"+mybox1);


        System.out.println(" The address of the object mybox2 is :"+ System.identityHashCode(mybox2));
        System.out.println(" The value of the mybox2 object is:"+mybox2);

    }
}

该程序的目标是帮助我理解Java中对象创建和内存分配的概念。根据我的理解,new运算符应为对象创建一个内存并返回存储在内存中的引用。为了获取对象的地址,我使用的是System.identityHashCode函数。为了获得存储在该内存地址中的引用的值,我直接打印该对象。下面我们可以看到结果。

 The address of the mybox object is:1956725890

 The value of the mybox object is:Box@74a14482

 The address of the object mybox1 is :1956725890

 The value of the mybox1 object is:Box@74a14482

 The address of the object mybox2 is :356573597

 The value of the mybox2 object is:Box@1540e19d

基于以上结果,我的理解是mybox和mybox1将具有相同的地址,并且它们将在该地址中携带相同的参考值,因为mybox1未实例化并已分配给mybox。 mybox2应该有一个新地址,它将在该地址中有一个新的参考值。

所以我的问题是

  • 如果没有实例化,mybox1将如何在该地址中拥有地址和引用?

  • 本书Java完整参考确实提到实例化后的每个对象都应该保存实际对象Box的内存地址。所以为什么存储在mybox2中的引用值不同于存储的引用值在mybox中?我假设只是通过打印变量,它会给我存储在该变量中的值,这是对象Box的引用。

感谢大家的任何建议,可以帮助我理解java的基本概念。我是一个新手,我非常感谢stackoverflow成员传播的丰富知识。

4 个答案:

答案 0 :(得分:0)

a)行Box mybox1= mybox;使变量mybox1指向由mybox变量创建的 Object 。因此,变量myboxmybox1都指向同一个对象。请注意,new运算符仅在前两行中使用一次。

b)由于您要在行mybox2中为Box mybox2 = new Box();创建一个新对象,它将在堆中创建一个全新的对象。您看到的变量myboxmybox2的值基本上是类的名称,后跟十六进制格式的对象的哈希码。

使用mybox打印变量System.out.println()时,它在内部执行toString方法:

  

类Object的toString方法返回一个字符串,该字符串由对象为实例的类的名称,符号字符“@”和对象的哈希码的无符号十六进制表示组成。换句话说,此方法返回一个等于值的字符串:

     

getClass().getName() + '@' + Integer.toHexString(hashCode())

答案 1 :(得分:0)

a)myBox1指向myBox,这就是为什么当你打印它的引用时,它与myBox相同。以下内容可能有助于您理解:

Box myBox;

我们刚刚在堆栈中创建了一个Box类型的实例变量,指向null。

myBox = new Box();

new运算符在堆上分配了一个对象,并将其指针返回给myBox。

Box myBox1 = myBox;

我们在堆栈上创建了另一个实例变量,该变量指向myBox所指向的相同引用。

现在,如果我们操纵myBox1并尝试访问myBox,如:

myBox1.height = 1;
System.out.println(myBox.height);

输出应为1,因为myBox和myBox1都指向相同的引用。

b)由于2个实例变量myBox2和mybox指向内存中的不同对象,因此根据this answer,identifyhashcode方法可能返回不同的值,因为它可能取决于对象所在的引用。

  

identityHashCode返回的整数可能与(a)对象的机器地址有关,也可能不是。 identityHashCode()返回的值保证在对象的生命周期内不会改变。

答案 2 :(得分:0)

它的模拟时间!

你可以想象一个变量(mybox,mybox1和mybox2)是孩子。并且他们可以使用字符串来保存气球(不要与Java中的String混淆,我的意思是实际字符串)。气球是对象,字符串是引用。

在第一行代码中,mybox持有一个字符串,该字符串连接到1956725890处的气球。现在在第2行中,mybox1也接受一个字符串并将其连接到1956725890处的气球。这就是这段代码的作用,

Box mybox1 = mybox;

在代码的第三行,

Box mybox2 = new Box();

另一个孩子,接受一个字符串并将其连接到另一个盒子,而不是1956725890的那个盒子。

对于你的第一个问题,答案是,

  

那是怎么回事。

正如我上面所说,代码的第二行复制了引用。关键是,没有创建新对象,只是一个新的引用。所以是的,没有实例化。

对于你的第二个问题,我真的不明白你在这里问的是什么。因为mybox当然拥有不同的引用,因此与mybox2不同。

正如我之前所说,第3行正在创建另一个对象并创建对该对象的新引用。那他们为什么要一样呢?

答案 3 :(得分:-1)

变量myboxmybox2包含对两个不同对象的引用。

Box a=new Box();

a是对象的引用

Box b;

b是对null

的引用

所以关键字“new” 创建一个新对象并存储它。

此对象的地址存储在变量中。