2013-10-08 58 views
0

比方說,我有這樣的Java代碼(中期審查!):的Java:對象指針處理

public class A { 
public int key; 
} 

public class B extends A { 
} 

public class Problem1 { 
public static void f(A x) { 
A y = x; 
y.key = x.key + 1; 
} 

public static void f(B x) { 
B y = new B(); 
y.key = x.key + 2; 
x = y; 
} 

public static void main(String[] args) { 
A p = new A(); 
p.key = 3; 
B q = new B(); 
q.key = 10; 
f(p); 
f(q); 
p = q; 
f(p); 
System.out.println(p.key); 
} 
} 

我不知道我正確理解P = Q。這是我迄今爲止的理解:因爲B擴展了A,所以這個操作是允許的,但它不會使p和q指向同一個對象。相反,它更新了p的關鍵值,但它仍然是A類。這就是爲什麼f(p)在最後返回11的原因。這並不符合我以前對Java的瞭解,因此我們將對此作出解釋。

例如,如果我有一個整型A = 4和INT B = 3,那麼我這樣做:

a = b; 
b++; 
return a; 

一個將返回3,即使它應該是指向將b指向同樣的事情?

請指教。

+3

原始對象的處理方式不同。如果在你的例子中你有Integer而不是int,它將按你的預期工作。 – sashkello

+0

查看第二個答案在這裏:http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java – sashkello

回答

1

想一想。 Java基本保持在存儲字節區域的實際值: 所以,如果a = 4b = 3,那麼8個字節的機器內存區域可容納像(二進制)

a = 0 0 0 0 0 0 1 1 
b = 0 0 0 0 0 0 1 0 

現在,當你說a=b;手段

a = 0 0 0 0 0 0 1 0 
b = 0 0 0 0 0 0 1 0 

然後b++ (i.e. b = b+1)

a = 0 0 0 0 0 0 1 0 
b = 0 0 0 0 0 0 1 1 

然後

return a; 

Then a = 0 0 0 0 0 0 1 0 (i.e. 3) 

希望你對原始值有所瞭解。雖然對於java中的一個對象,但這完全是另一種情況。

現在認爲,a和b不是原始的,而是具有int字段的對象。 A樣本類可能看起來像

class Test { 
private int value; 

public Test(int value){ 
this.value = value; 
} 

public int getValue(){ 
return value; 
} 

public int increment(){ 
value++; 
} 
} 

然後a = new Test(4); and b = new Test(3);在存儲器等爲代表:

堆:

a = x63489DF8 ---> [Test(4) Object, value = 4, Heap Memory address = x63489DF8] 
b = xDFA78945 ---> [Test(3) Object, value = 3, Heap Memory address = xDFA78945] 

ab保持指向該對象堆存儲器地址)

現在,當你說a=b;意味着

a = xDFA78945 ---> [Test(3) Object value = 3, Heap Memory address = xDFA78945] 
b = xDFA78945 ---> [Test(3) Object value = 3, Heap Memory address = xDFA78945] 

(在存儲器地址x63489DF8對象是垃圾收集的和a, b指的是同一個對象)

現在,假設b .increment();然後在存儲器區域xDFA78945對象被操縱和新對象變爲[Test(3) Object value = 4, Heap Memory address = xDFA78945]

a = xDFA78945 ---> [Test(3) Object value = 4, Heap Memory address = xDFA78945] 
b = xDFA78945 ---> [Test(3) Object value = 4, Heap Memory address = xDFA78945] 

(注意變化體現爲參照,因爲兩者實際上是指向同一個對象)

現在回到a.getValue()返回4 (即通過參考b做變化反映早在參考a如孔)

0

例如,如果我有一個INT = 4和INT b = 3,然後我做的:

a = b; 
b++; 
return a; 

a將返回3,即使它應該指向b指向的相同東西 ?

原始材料按照您的預期處理。換句話說,a會給出值3,因爲它佔用了b的數值或位值。但是,您應該查看autoboxingimmutability

我不知道我是否正確理解p = q。這是我的理解,因此 遠:因爲B擴展A,這個操作是允許的,但它不 使p和q指向同一個對象。相反,它更新p的關鍵 值,但它對於保持A級

的對象,操作p = q沒有實際分配P,使得它「是指」(見文末鏈接),以相同的對象爲q。這就是爲什麼像defensive copying這樣的方法是必要的。

這也解釋了爲什麼儘管Java passing by value通過重載的f方法進行修改。參數x保持不變,只要進程離開方法範圍就消失,但可以修改引用的對象的狀態

下面是一個問題,討論C指針和Java引用之間的區別。

https://softwareengineering.stackexchange.com/questions/141834/how-is-a-java-reference-different-from-a-c-pointer

0

所有變量位持有人。好吧

所以如果它是原始類型,它將保留代表原語的位代表 的位。

a = b; b++; return a; 

這裏位「3」的表示被分配給「a」,所以它現在是3。但是b仍然保持代表「3」的位,所以b中的cange將堅持只是「b」

現在如果a是類變量並且b也是在java變量中總是保存位。當它是類 varible它擁有代表到達生活在堆上的類對象的路徑的位。所以當你做這個a = b; a也將舉行路徑到達堆積的物體。所以「a」和「b」兩者都保持同一物體的路徑。

如果您更改「a」屬性(更改通過由var「a」指向的路徑達到的對象的屬性)。將反映在b。因爲這些指向相同的變種。 enter image description here