Java中傳值和傳址

本文用一下代碼說明: java

Java代碼  收藏代碼 app

簡單字符串String: 函數

  1. package luojing;  
  2. public class StringDemo  
  3. {  
  4.     public static void main(String[]args)  
  5.     {  
  6.         String str=new String("hello");  
  7.         //調用函數改變str的值  
  8.         change(str);  
  9.         System.out.println(str);  
  10.           
  11.     }  
  12.       
  13.     public static void change(String str1)  
  14.     {  
  15.         str1+="luojing";  
  16.     }  
  17. }  
程序執行結果:  hello

StringBuffer: this

  1. public class StringDemo  
  2. {  
  3.     public static void main(String[]args)  
  4.     {  
  5.         StringBuffer str=new StringBuffer("hello");  
  6.         //調用函數改變str的值  
  7.         change(str);  
  8.         System.out.println(str);  
  9.           
  10.     }  
  11.       
  12.     public static void change(StringBuffer str1)  
  13.     {  
  14.         str1.append("luojing");  
  15.     }  
  16. }  
程序運行結果 :hello luojing        這個時候str的內容就改變了。


將上面的StringBuffer換成咱們本身定義的對象: spa

  1. public class test  
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         Demo demo=new Demo("hello");  
  6.         //調用函數該變demo.name的值  
  7.         change(demo);  
  8.         System.out.println(demo.getName());  
  9.       
  10.     }  
  11.       
  12.     public static void change(Demo d)  
  13.     {  
  14.         d.setName("luojing");  
  15.     }  
  16.   
  17. }  
  18.   
  19. class Demo  
  20. {  
  21.     private String name;  
  22.       
  23.     public Demo(String s)  
  24.     {  
  25.         name=s;  
  26.     }  
  27.     public String getName()  
  28.     {  
  29.         return name;  
  30.     }  
  31.     public void setName(String str)  
  32.     {  
  33.         name=str;  
  34.     }  
  35. }  
程序運行結果: luojing  和咱們使用StringBuffer對象是效果相同。

咱們再對change()方法作一些修改: .net

  1. package luojing;  
  2. public class test   
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         Demo demo=new Demo("hello");  
  7.         //調用函數該變demo.name的值  
  8.         change(demo);  
  9.         System.out.println(demo.getName());  
  10.       
  11.     }  
  12.       
  13.     public static void change(Demo d)  
  14.     {  
  15.         Demo d1=new Demo("hello java");  
  16.         d=d1;     
  17.     }  
  18.   
  19. }  
  20.   
  21. class Demo  
  22. {  
  23.     private String name;  
  24.       
  25.     public Demo(String s)  
  26.     {  
  27.         name=s;  
  28.     }  
  29.     public String getName()  
  30.     {  
  31.         return name;  
  32.     }  
  33.     public void setName(String str)  
  34.     {  
  35.         name=str;  
  36.     }  
  37. }  
運行結果: hello
     能夠看到,雖然咱們在change()方法中對d進行了改變,而實際的對象demo並無改變。


  1. class Foo {  
  2.    private int x;  
  3.    public Foo(int x) {  
  4.       this.x = x;  
  5.     }  
  6.     public void setX(int x) {  
  7.        this.x = x;  
  8.     }  
  9.     public int getX() {  
  10.        return x;  
  11.     }  
  12. }  
  13.   
  14. public class Submit {  
  15.     static Foo fooBar(Foo foo) {  
  16.         foo = new Foo(100);  
  17.         return foo;  
  18.    }  
  19.    
  20.     public static void main(String[] args) {  
  21.         Foo foo = new Foo(300);  
  22.         System.out.print(foo.getX() + "-");  
  23.    
  24.         Foo fooFoo = fooBar(foo);  
  25.         System.out.print(foo.getX() + "-");  
  26.         System.out.print(fooFoo.getX() + "-");  
  27.    
  28.         foo = fooBar(fooFoo);  
  29.         System.out.print(foo.getX() + "-");  
  30.         System.out.print(fooFoo.getX());  
  31.     }  
  32. }  



What is the output of the program shown in the exhibit? 
A. 300-100-100-100-100 
B. 300-300-100-100-100 
C. 300-300-300-100-100 
D. 300-300-300-300-100 

Answer: B 

涉及知識點: 
1.Java中的參數傳遞有傳值和傳址兩種; 
2.基本類型和String型做爲參數時,爲傳值方式,只把值傳入方法,無論在方法中怎麼處理這個參數,原值不變; 
3.其餘引用類型做爲參數時,爲傳址方式,將指向內存中的地址傳入方法,方法中此內存地址中的值發生變化時,原值也會改變; 
4.例外: 
    (1)若是引用類型的對象經過傳址方式將其指向內存中的地址傳入方法後,方法中使用new關鍵字從新給參數賦值時,會在內存中從新開闢空間,參數指向新的內存空間,此時參數和原對象指向的就不是同一個地址了,參數值的變化不會改變原值; 
    (2)String型是引用類型,可是String型做爲參數,是傳值方式,能夠經過如下兩種方式來理解: 
        <1>String本質上是基本類型的char[],基本類型做爲參數時,爲傳值方式; 
        <2> 字符串在內存中是存儲在堆中的一個常量,String對象指向內存中這個常量的地址,經過傳址方式將地址傳入方法後,方法中若是經過字符串給參數賦值,則會從新在堆中建立一個字符串常量,並指向這個地址,原值依然指向原來的字符串常量地址,參數值的變化不會改變原值,若是經過new關鍵字給參數賦值,參見 (1)中的解釋。 


解析: 
1.「Foo foo = new Foo(300);」,此時foo.getX()的值爲300; 
2.「Foo fooFoo = fooBar(foo);」,由於Foo是引用類型,main方法中的foo經過傳址的方式將其指向的地址傳給fooBar方法中的foo,此時兩個foo指向同一個地址,foo.getX()的值都爲300;經過「new Foo(100)」給fooBar方法中的foo賦值後,該foo從新指向了一個新的地址,foo.getX()的值爲新地址中的值100,而main方法中的foo仍然指向原來的地址,foo.getX()的值沒有改變,仍爲 300;fooBar將foo的值返回給fooFoo,所以fooFoo.getX()的值爲100; 
3.「foo = fooBar(fooFoo);」,同2中的解釋,foo.getX()的值變爲100,fooFoo.getX()的值沒有變化,仍爲100; 
相關文章
相關標籤/搜索