2015-06-16 63 views
-1

我知道这个问题以前已经问过,但我找不到满意的答案。 假设一个Java类:是一个Java类变量对类对象的引用吗?

class Foo{ 
    public int k; 
    Foo(int a){ 
     k=a; 
    } 
} 
class My{ 
    public static void main(String args[]){ 
     Foo obj = new Foo(5);//1 
     obj=new Foo(8); //2 
    } 
} 

我想知道如果obj可以被假定为是一个Foo类型的对象的引用。按照我在第1行中的理解,JVM创建一个新的foo类型的对象,并将其引用传递给obj,但是在第2行中,我们能够用新对象覆盖obj的值。

所以我的问题是,如果obj是一个引用,那么它不应该只指向一个对象(从C++派生这个定义,引用就像常量指针)。

回答

1

obj是对foo类型的对象的引用,您的理解是正确的。在第1行中,JVM创建foo类型的新实例(ojbect)(新内存分配在堆中),并且obj现在存储对该内存位置的引用,假设内存位置为1001。所以一个行之后 -

obj -> 1001 

2号线之后,JVM创建同一类型foo的新对象(即完全新的内存在堆中分配),可以说这一次2001,是分配给新的记忆对象,现在在第2行之后,obj的引用被更新并从1001更改为2001

obj -> 2001 

2号线后,在内存中的位置1001分配的对象不具有代码中的任何引用,所以最终JVM将垃圾收集的内存,这意味着,它会释放内存弥补其他对象的未来分配。在Java中的引用不像C++,它们不是常量指针,你可以把它们看作是来自C++的正常的pointers,你可以随时改变它指向/指向的内存位置,它必须是同一类型的存储器位置,即该对象必须是相同的类型(foo

+0

还有一件事,如果我将obj传递给一个函数,并且该函数对它做了一些更改,这些更改是否也会反映到主函数范围中? –

+0

是的,就像C++一样,当你传递指向C++函数的指针,并在函数内部对指针指向的内存位置进行任何更改时,它也反映在其他函数中(这称为'by reference by reference') ,它对于java对象是一样的,当你将java对象传递给函数时,它们通过'reference'传递,对象内部的任何变化都会被反映出来。但请注意,就像C++一样,如果直接更改完整对象本身,可以说一行像'argument = new Foo(10)',它们将不会被反映出来,与C++ –

+0

一样,非常感谢。 –

1

你的理解是完全正确的。 obj现在指向第二个foo对象。在这种情况下,foo(5)不会被任何对象引用,并且会被JVM垃圾收集。

+0

在第二部分我问,如果通过定义参考像恒定指针(C++),然后如何它的值初始化后偶然? –

+0

你为什么认为他们是不变的指针?不,他们不是常数指针。 –

1

Foo obj创建Java中的reference variable可保持参考该类的一个对象的。

new Foo();声明实际上创建了一个对象。多次写入new Foo();会创建一个新对象。

如果obj是基准然后should'nt它只指向一个物体

不,它不是这种情况。它不是任何种类的限制,只有一个参考变量只能指向一个对象。它可以指向任何对象。

我会说,这是类似于以下,

int a = 10; 
a = 15; 

而其他用户已经发布,Java中的对象,它没有引用变量指向它,可以进行垃圾回收。

0
Foo obj = new Foo(5);//1 

宣言+实例化+初始化

obj = new foo(8); 

实例化+初始化

在你的程序中,我打印的obj之前和之后 '的obj =新富(8);'线

foo obj = new foo(5);// 1 
System.out.println("Before:" + obj); 
obj = new foo(8); // 2 
System.out.println("After:" + obj); 

和输出

Before:[email protected] 
After:[email protected] 

您可以轻松地从这个输出是new foo(8);声明实际上创建了一个新的对象理解。

有关详细看到Java文档Creating Objects