2012-02-02 102 views
0

我正在閱讀關於通過值傳遞和在Java中通過引用傳遞,我收到了很多文章,其中一些人說Java只跟隨「按值傳遞」,其中一些說一些原始和對象之間的區別。所以我寫了下面的示例代碼。 並把輸出也。 請評論並共享究竟是什麼,答案是。在java中傳遞值和通過引用傳遞

我檢查了詮釋,字符串,StringBuffer的和Employee類,現在它的工作僅作爲員工類別的參考。

package test; 
class Emp { 
    public String name=""; 
    public int age=0; 

    public Emp(String name, int age) { 
     super(); 
     this.name = name; 
     this.age = age; 
    } 
    public String toString() { 
     return "Name: "+ this.name + "....Age: "+ this.age; 

    } 
} 
public class Class1 { 
    public Class1() { 
     super(); 
    } 

    public void doChange(int i) { 
     i = i +10; 
     System.out.println("Value of Integer in Method:>"+ i); 
    } 

    public void doChange(Emp i) { 
     i.age=29; 
     i.name="rishu"; 
     System.out.println("Value of Employee In Method "+i.toString()); 
    } 

    public void doChange(String i) { 
     i = i + " Hello"; 
     System.out.println("value of i->"+ i); 
    } 


    public static void main(String[] args) { 
     int i =10; 
     String str="XXX"; 
     Class1 c= new Class1(); 
     StringBuffer sb= new StringBuffer(); 
     Emp e= new Emp("abhi",28);  

     sb.append("ABC "); 
     System.out.println(""); 
     System.out.println("Value of Integer before Method:->"+ i); 
     c.doChange(i); 
     System.out.println("Value of Integer after Method:->"+ i); 
     System.out.println(""); 
     System.out.println("Value of String before Method:->"+ str); 
     c.doChange(str); 
     System.out.println("Value of Integer after Method:->"+ str); 
     System.out.println(""); 
     System.out.println("Value of StringBuffer before Method:->"+ sb); 
     c.doChange(sb.toString()); 
     System.out.println("Value of StringBuffer after Method:->"+ sb); 
     System.out.println(""); 

     System.out.println("Value of Employee before Method:->"+ e.toString()); 
     c.doChange(e); 
     System.out.println("Value of Employee after Method:->"+ e.toString()); 
    } 
} 

輸出:

Value of Integer before Method:->10 
Value of Integer in Method:>20 
Value of Integer after Method:->10 

Value of String before Method:->XXX 
value of i->XXX Hello 
Value of Integer after Method:->XXX 

Value of StringBuffer before Method:->ABC 
value of i->ABC Hello 
Value of StringBuffer after Method:->ABC 

Value of Employee before Method:->Name: abhi....Age: 28 
Value of Employee In Method Name: rishu....Age: 29 
Value of Employee after Method:->Name: rishu....Age: 29 
+0

請參閱:http://stackoverflow.com/questions/40480/ is-java-pass-by-reference – 2012-02-02 09:05:23

+0

這是'i.name =「rishu」'和'i = rishu'(或'i = new Emp(「rishu」,...)')之間的很大區別。第一個是改變'i'中的對象_saved_,第二個改變'i'本身。 – 2012-02-02 09:19:53

回答

10

Java只是按值傳遞。

但是,對於對象,通過值傳遞的是對對象的引用。不,這與通過引用不一樣。所不同的是:

如果你這樣做:

public void doChange(Emp i) { 
    i = new Emp("changed!", 42); 
} 

它的方法之外絕對沒有任何影響 - 因爲引用i是法外使用的引用的副本。但是,它指的是同一個對象,因此如果使用引用來更改對象的字段,則這些更改在方法外部是可見的。

+0

很好的答案,但修復了錯字:..它指的是相同的_object_,所以... – quaylar 2012-02-02 09:24:51

+0

@quaylar:謝謝,完成 – 2012-02-02 09:34:00

+0

所以用同樣的方式爲什麼字符串緩衝區不工作。 – Pedantic 2012-02-02 10:08:24

1

沒有通通過在Java引用,僅通過值傳遞。

當此方法退出時,員工將不會成爲下巴,而是在您輸入此方法之前設置的其他東西。

public void doChange(Emp i) { 
    i = new Emp("chin boon", 42); 
} 

此方法退出時,員工將有名字下巴福音。

public void doChange(Emp i) { 
    i.setName("chin boon"); 
} 
+0

真的非常感謝,請幫我理解Employee類是如何工作的。我在修改String和StringBuffer的方法中進行了修改。 – Pedantic 2012-02-02 09:07:41

1

Java使用按值傳遞語義將參數傳遞給方法。也就是說,方法調用的每個指定參數的copy of the value作爲其參數傳遞給該方法。

很清楚地注意到,很多人混淆了關於Java對象引用和引用調用語義的「引用」術語。事實上,在處理Java對象的引用時,引用值的副本是傳遞給方法的 - 它是通過值傳遞的。例如,這就是爲什麼你不能在被調用的方法內改變對象的(原始的,調用者的)引用。

例如:

Dog aDog = new Dog("Max"); 

要定義一個指針指向一個狗aDog對象,而不是狗對象本身。

public void foo(Dog d) { 
    d = new Dog("Bingo"); 
} 

傳入的變量未被修改!打電話給foo後,狗仍然指向「最大」狗。將d的值傳遞給foo,指針的值與存儲器地址相似。整數的

1

值方法之前: - 在整型方法> 10值:> 20值整數的方法後: - > 10

沒有這裏的驚喜。您將10的值傳遞給方法,它會遞增並正確顯示。從方法調用返回後,i變量保持不變。方法之前字符串的

值: - > XXX的價值I->方法後整型XXX你好值: - > XXX

字符串是不可變類,所以也沒有辦法去改變它。您只能重新分配價值,就像您在示例中所做的那樣。這裏的訣竅是瞭解,您會收到一個導致對象XXX的複製參考值。現在,您正在創建新對象i + "Hello"並覆蓋以前的參考i。因此,對象XXX不會更改,但是在您未打印的方法中 - 您正在打印在方法中創建的對象。的StringBuffer

值法之前: - :> ABC

這是相同的情況下,如在上面的代碼中,由於toString() - 的I->方法後的StringBuffer的ABC你好值> ABC值產生一個新的String對象。

最後:員工的

值前法: - >名稱:ABHI ....年齡:日書....年齡:員工在方法名28後的價值員工的價值29方法: - >名稱:日書....年齡:29

這是按值傳遞 您正在創建對象Employee的完美展示,但你傳遞一個參考這個對象的方法參數。現在,記住這個爲終身,這個引用是複製,所以你會收到一份參考副本可供您使用的方法內。 這就是爲什麼JAVA始終通過複製。 但是,此複製的引用仍指向您之前創建的同一個對象Employee。因此,如果您將使用該引用來修改其指向的對象,那麼可以修改原始Employee。這就是爲什麼你可以看到輸出中的變化效果。

Bruce Eckel有一個很好的Java引用和對象的例子。將對象視爲電視,並將其視爲遙控器。如果您將引用其他方法作爲參數傳遞,您將在此方法中使用複製的遠程控制。如果在方法內按下「關閉」按鈕,即使您沒有使用原始遙控器,電視仍然會最終關閉;)