`
unique5945
  • 浏览: 132023 次
  • 来自: 杭州
社区版块
存档分类
最新评论

java的值传递

    博客分类:
  • JAVA
阅读更多
先看以下代码:
class Person {
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public static void main(String[] args) {

		Person person = new Person();//---1
		Person p2 = new Person();
		person.setAge(12);
		person.setName("lj");
		test.changePerson(person,p2);//---2 该处person不同于1处的person,而是前者的一个拷贝,他们指向堆中同一个对象
		System.out.println("in main...");
		System.out.println("person.age:" + person.getAge());
		System.out.println("person.name:" + person.getName());
	}
	void changePerson(Person p1,Person p2){
		p2.setAge(13);
		p2.setName("yb");
		p1 = p2;
		System.out.println("in changePerson...");
		System.out.println("person.age:" + p1.getAge());
		System.out.println("person.name:" + p1.getName());
	}
}

运行结果:
in changePerson...
person.age:13
person.name:yb
in main...
person.age:12
person.name:lj
也许会很奇怪,java对象在方法里传递时不是引用传递么?为什么传过去的person在changePerson()方法体内把引用指向了p2,但回到主方法后又把引用指向了原来的对象
原因如下:
                              
主函数中: person--> [age:12 name:lj] <--person’
                      
person'即为test.changePerson(person,p2); 中的person,它与前面的person具有相同的引用地址,因此java中的“对象变量”的传递叫做“引用传递”。但就其实质而言,还是值传递,只不过这个值是引用(或者说地址)而已。

changePerson函数中:person对象的拷贝p1又把引用指向了另一个对象p2,所以会打印出新对象的信息,而当这个函数结束,p1的生命周期也就结束了。
再次回到主函数时,person对象指向原来的对象的事实没有改变,所以还是打印出原来对象的信息

如果还有一个函数changePerson2如下:
void changePerson2(Person p){
	p.setAge(100);
	p.setName("ljyb");
}

则在主函数增加如下代码:
test.changePerson2(person);
System.out.println("in changePerson...");
System.out.println("person.age:" + person.getAge());
System.out.println("person.name:" + person.getName());
结果为:
after invoking changePerson2...
person.age:100
person.name:ljyb

此时的传递方式与上面相同,changePerson2中的p变量也是主函数中person变量的一份拷贝,他们指向同一个对象。p改变了这个对象的值,也就改变了person指向对象的值。
当changePerson2函数结束时,p的生命周期也结束了,但它在changePerson2内做的操作却被保存下来了。
此时打印person的信息就变成修改后的信息了。

我还找到一些相关资料,附下
下面的文字来自一个哥们的文章中的评论,他写的这篇文章也是关于java值传递的
网址:http://zangweiren.iteye.com/blog/214369

有些争论没有意义,其实你知道传值和传引用由什么区别就可以了,但不要自以为是的认为就是别人混淆了。
“有一种说法是当一个对象或引用类型变量被当作参数传递时,也是值传递,这个值就是对象的引用,因此JAVA中只有值传递,没有引用传递。这种说法显然是混淆了值和引用的概念。”
我看到的很多书中都是只有pass by value的概念。
James Gosling,我想他对Java语言里的一些概念还是有话语权的,《The Java Programming Language》2.6.5. Parameter Values一节中,他的说法是 :
引用
All parameters to methods are passed "by value." In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments.。。。。。You should note that when the parameter is an object reference, it is the object reference not the object itself that is passed "by value." Thus, you can change which object a parameter refers to inside the method without affecting the reference that was passed. But if you change any fields of the object or invoke methods that change the object's state, the object is changed for every part of the program that holds a reference to it.
这里说的很清楚了,方法的所有参数都是值传递。

别的书里也有提及 ,Core Java 卷一中也有类似的说法,举了一些例子。
Thinking In Java中也提到过,具体什么地方记不清楚了。
从编译原理的概念来说,有传值,传地址,传名,传结果等。这里的传地址明显和java的传引用不一样。C++中引入了传引用,但是C++的传引用有个明显的特点,引用一旦创建不能修改,所以引用不能指向新的对象。所以不会出现java这种令人混淆的概念。所以还是多用Java中的术语,区分pass by value中不同的情况,而不是自己引入pass by reference 的概念让人们更加混淆。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics