2015-06-16 21 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