关于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,1 in 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;
@Override
public 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,18 man,20 in main method : man,20 in 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,18 man,20 in main method : woman,18 in main method : woman,18
我们可以看到main方法中user1的值也发生了改变,是因为在objChange()中,我们传递的引用他的指针改变了并且我们在函数中将已经改变了的new1作为一个新的User对象return了回来,并且在main中将他指向了user1,所以main中user1的值发生了改变。
故此得出,Java中当传递一个对象的是时候我们并没有去传递这个对象本身,而是传递的是指向这个对象指针的一个副本,我们在函数中所操作的是这个对象的副本而不是对象本身。这个是本人对java传递对象的理解,如果有不对的地方大家可以互相指正讨论。
原文参考:http://fuliang.iteye.com/blog/69313
原文:http://my.oschina.net/u/1273696/blog/478156