標籤:
關於java對象和傳值得問題,偶然間在看js的時候,發現的一個無效轉換對象資料的問題,自己感覺有點疑惑,以為是js的特性,隨機想在java上面證實一下,結果發現並不是js的特性,java也是如此然後查了些許資料發現自己學習的疏忽,當時確實驚出了一身冷汗呀,現在就具體說下問題:
在做值轉換的時候碰到了如下情況
樣本1:
public static void intValueChange(int a,int b){int temp = a;a = b;b = temp;System.out.println(a+","+b);}
public static void main(String[] args){int a = 1; int b = 2;intValueChange(a,b);System.out.println("in main method : "+a+","+b);}
輸出結果是:
2,1in main method : 1,2
發現在intValueChange()內部,變數a,b的值發生了改變,但是main方法中的a,b並沒有發生改變
再看以下例子
樣本2:
public static void main(String[] args){User user1 = new User("man","20");User user2 = new User("woman","18");objChange(user1,user2);System.out.println("in main method : "+user1.toString());System.out.println("in main method : "+user2.toString());}public static void objChange(User new1, User new2){User temp = new1;new1 = new2;new2 = temp;System.out.println(new1.toString());System.out.println(new2.toString());}static class User{public User(){}public User(String name,String age){this.name = name;this.age = age;}private String name;private String age;@Overridepublic String toString(){return this.name + "," + this.age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}}
輸出結果:
woman,18man,20in main method : man,20in main method : woman,18
同樣我們可以發現在objChange()內部,變數user1,user2的值發生了改變,但是main方法中的user1,user2並沒有發生改變,下來我們再看一個執行個體:
樣本3:
public static void main(String[] args){User user1 = new User("man","20");changeUser(user1);System.out.println(user1);}public static void changeUser(User user1){user1.name = "test1";user1.age = "100";}
輸入結果:
in main method : test1,100
這次我們發現在main方法中對象的值竟然發生了變化,之所以會有以上變化,是因為java在傳遞實參的時候,傳遞的是這個實參的指標,在傳遞的過程中,對指標進行了複製可以這麼來理解
user1--->User對象1
user2--->User對象2
在執行方法objChange(User new1,User new2)的時候,並沒有直接將user1和user2傳過來,因為傳遞對象不是那麼簡單,而是傳遞了一個user1和user2對象的副本(即他們的指標):
user1--->User對象1 <---new1
user2--->User對象2 <---new2
進入函數之後我們改變的是副本的引用,而不是user1和user2的引用:
user1--->User對象1 <---new2
user2--->User對象2 <---new1
這樣我們就能明確的看到改變的是user1和user2的副本,但是user1和user2本身並沒有變化,因此就可以解釋為什麼總是在函數內部值發生了改變了;
接下來執行個體3是因為在函數內部,傳遞的副本修改了指標本身的值,所以我們就會在main中看到user1的值修改了
接下來我們根據執行個體2和執行個體3,再來看執行個體4
public static void main(String[] args){User user1 = new User("man","20");User user2 = new User("woman","18");user1 = objChange(user1,user2);System.out.println("in main method : "+user1.toString());System.out.println("in main method : "+user2.toString());} public static User objChange(User new1, User new2){User temp = new1;new1 = new2;new2 = temp;System.out.println(new1.toString());System.out.println(new2.toString());return new1;}
輸出結果:
woman,18man,20in main method : woman,18in main method : woman,18
我們可以看到main方法中user1的值也發生了改變,是因為在objChange()中,我們傳遞的引用他的指標改變了並且我們在函數中將已經改變了的new1作為一個新的User對象return了回來,並且在main中將他指向了user1,所以main中user1的值發生了改變。
故此得出,Java中當傳遞一個對象的是時候我們並沒有去傳遞這個對象本身,而是傳遞的是指向這個對象指標的一個副本,我們在函數中所操作的是這個對象的副本而不是對象本身。這個是本人對java傳遞對象的理解,如果有不對的地方大家可以互相指正討論。
原文參考:http://fuliang.iteye.com/blog/69313
java對象引用和對象值得行為