2014-07-26 27 views
3

我敢打賭,這個問題已經得到解答,但我不知道如何用簡單的語言來解釋這個問題在谷歌上找到一個簡單的答案 - 我很抱歉!讓一個方法修改引用,而不是一個新的對象

這是我的測試代碼:

public class test { 
public static void increase(Integer i){ 
    i++; 
} 

public static void main(String[] args){ 
    Integer x = new Integer(10); 
    increase(x); 
    System.out.println(x); 
} 

}

我有一個整數x,並希望通過一個空洞的方法 「增加(..)」 進行修改。由於Integer是一個對象,所以x是一個指向該對象的指針。 我想「增加(..)」來修改Integer本身,所以「i」指的是與「x」相同的對象。但是,如果我看看print(x)(它是「10」),我認爲該方法創建一個新的整數與「x」的內容。

我希望能理解我...

我需要什麼?

我想使用多個線程來總結從1到「n」的數字。 我創建了一個類「MyThread」,它得到一個lowerLimit和一個upperLimit來總結區間,以及一個「結果」(但是作爲參考 - 而不是一個新的對象),這些區間的數量被加到上面。

問候 Tak3r07

回答

3

有三種方法可以做到這一點。

public class test { 
public static void increase(AtomicInteger i){ 
    i.getAndIncrement() 
} 

public static void main(String[] args){ 
    AtomicInteger x = new AtomicInteger(10); 
    increase(x); 
    System.out.println(x); 
} 
} 

public class test { 
public static void increase(int[] i){ 
    i[0]++; 
} 

public static void main(String[] args){ 
    int[] x = { 10 }; 
    increase(x); 
    System.out.println(x[0]); 
} 
} 

或整數

public class test { 
public static void increase(Integer[] i){ 
    i[0]++; 
} 

public static void main(String[] args){ 
    Integer[] x = { 10 }; 
    increase(x); 
    System.out.println(x[0]); 
} 
} 

出於興趣,你能解釋一下爲什麼這個工作?我認爲Java嚴格按照價值傳遞?

Java是通過價值。引用是按值傳遞的,但這是一個淺層而不是深層複製。即您不能更改引用,但可以更改引用的對象。

你不能直接用Integer這樣做,因爲它是不可變的,所以沒有什麼可以改變的。傳遞一個可變對象的引用,你可以改變它。

+0

+1 Peter。出於興趣,你能解釋爲什麼這是有效的嗎?我認爲Java嚴格按照價值傳遞? (所以當你將一個對象傳遞給一個方法時,該方法與該對象的副本一起工作)。現在很困惑,爲什麼整數不工作,但一個int [] – Chris

+0

謝謝,這兩種好方法! – Tak3r07

+0

@Chris很好的問題,補充說明。 –

1

創建一個單獨的類,你想要做什麼:

示例代碼:

public class MyInteger { 
    int value; 

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

    public int getValue() { 
     return value; 
    } 

    public void setValue(int value) { 
     this.value = value; 
    } 

    public void increase() { 
     value++; 
    } 

    @Override 
    public String toString(){ 
     return String.valueOf(value); 
    } 

} 

.... 

public static void main(String[] args){ 

    MyInteger x = new MyInteger(10); 
    x.increase(); 
    System.out.println(x.getValue()); // print 11 
    System.out.println(x);    // print 11 

} 
2

Integer類像String和其他原始包裝類是不可變的,這意味着它們的值不能是因此每次嘗試更改其值時,實際上都會創建它們的新實例。爲此,您可以使用AtomicIntegerAtomicLong,AtomicDouble ...。

+0

感謝您的解釋。我想我已經聽說他們是不變的,但忘記了它。我認爲不可變類的派生是不可改變的? – Tak3r07

+2

@ Tak3r07,Immutables是最終的,這意味着你不能創建一個擴展它們的類。 – SteveL

2

形式e++的表達是

E old = e; 
e = (E) (old + 1); 
return old; 

其中Ee類型的簡寫。

也就是說,你的表達式相當於

i = (Integer) (i + 1); 

這是通過計算I + 1,創建(或重複使用)整數對象到保持該值,並存儲在參考該對象評價變量i。原始Integer對象未被修改,並且調用者仍然引用該原始對象,因此會看到原始值。

要解決此問題,您可以返回對新Integer對象的引用,並要求調用方存儲它,或將引用傳遞給支持更改該值的類的對象。唉,整數是沒有這樣的類,因爲它的值不能改變,一旦對象已經被創建。請參閱彼得和布拉傑的答案,找到合適的類的例子。

相關問題