当前位置: 首页 > Java > 正文

Java值传递与引用传递

1 星2 星3 星4 星5 星 (暂无评分)
Loading ... Loading ...
baidu_share

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

在《Thinking in Java》的一段内容(注解[1])里找到了自己的结论,可以说是值传递,也可以说是引用传递。

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法中执行形式参数值的改变不影响实际参数的值。

引用传递:也称为传地址。方法调用时,实际参数的引用(即地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法中执行对形式参数的操作实际上就是对实际参数的操作(地址操作),这样方法执行中形式参数值的改变将会影响实际参数的值。

传值—传递基本数据类型参数
引用传递—对象作为参数

如果在方法中把对象(或数组)作为参数,方法调用时,参数传递的是对象的引用(地址),即在方法调用时,实际参数把对对象的引用(地址)传递给形式参数。这是实际参数与形式参数指向同一个地址,即同一个对象(数组),方法执行时,对形式参数的改变实际上就是对实际参数的改变,这个结果在调用结束后被保留了下来。

一,认为是值传递。得出这种结论的前提必须是“参数的值就是对该对象的引用,而不是对象的内容”.

public class Paier {
 
     public static void main(String[] args) {
 
                    Paier paier = new Paier();
 
                    paier.test();
 
     }
 
 
 
     public void test() {
 
                    TestClass para1 = new TestClass();
 
                    para1.setTest(new Integer(10));
 
                    TestClass result1 = test1(para1);
 
                    System.out.println("para1   = " + para1.getTest());
 
                    System.out.println("result1 = " + result1.getTest());
 
 
 
                    TestClass para2 = new TestClass();
 
                    para2.setTest(new Integer(10));
 
                    TestClass result2 = test2(para2);
 
                    System.out.println("para2   = " + para2.getTest());
 
                    System.out.println("result2 = " + result2.getTest());
 
     }
 
 
 
     public TestClass test1(TestClass t) {
 
                    t = new TestClass();
 
                    t.setTest(new Integer(20));
 
                    return t;
 
     }
 
 
 
     public TestClass test2(TestClass t) {
 
                    t.setTest(new Integer(20));
 
                    return t;
 
     }
 
 
 
     class TestClass {
 
                    Integer test = null;
 
                    public void setTest(Integer i) {
 
                                  test = i;
 
                    }
 
                    public Integer getTest() {
 
                                  return test;
 
                    }
 
     }
 
}
 
执行后的结果是:
 
para1   = 10
 
result1 = 20
 
para2   = 20
 
result2 = 20

为什么会这样呢?因为test1想通过修改参数的引用来修改返回值,但是在JAVA中,参数的引用是不可修改的,所以para1和result1分别指向不同的空间,结果也不一样。而在test2中,result2和para2始终指向同一块区域,test2方法修改的是参数内容,而不是参数的引用。

从上面看来,因为参数的引用不可改变,如果理解为“参数的值就是对该对象的引用”,那么java自然只有值传递。

二,认为是引用传递。还是上面的例子,如果在参数传递时理解为“参数的值就是该对象的内容”,那么显然不是值传递,因为对象的内容已经改变了。

认为是引用传递还有一个理由,就是java有一个保留字byvalue,现在的JDK版本中还没有实现这个保留字,似乎是在暗示对这种观点的支持。(There appears to be some support for this view within Sun, since one of the “reserved but not implemented” keywords is byvalue.)

所以说,对于原题的结论,是值传递还是引用传递并不重要,重要的是要理解“对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。”

注解[1]:下面是在《Thinking in Java》中的原文:

This brings up the terminology issue, which always seems good for an argument. The term is “pass by value,” and the meaning depends on how you perceive the operation of the program. The general meaning is that you get a local copy of whatever you’re passing, but the real question is how you think about what you’re passing. When it comes to the meaning of “pass by value,” there are two fairly distinct camps:

1. Java passes everything by value. When you’re passing primitives into a method, you get a distinct copy of the primitive. When you’re passing a handle into a method, you get a copy of the handle. Ergo, everything is pass by value. Of course, the assumption is that you’re always thinking (and caring) that handles are being passed, but it seems like the Java design has gone a long way toward allowing you to ignore (most of the time) that you’re working with a handle. That is, it seems to allow you to think of the handle as “the object,” since it implicitly dereferences it whenever you make a method call.

2. Java passes primitives by value (no argument there), but objects are passed by reference. This is the world view that the handle is an alias for the object, so you think about passing handles, but instead say “I’m passing the object.” Since you don’t get a local copy of the object when you pass it into a method, objects are clearly not passed by value. There appears to be some support for this view within Sun, since one of the “reserved but not implemented” keywords is byvalue. (There’s no knowing, however, whether that keyword will ever see the light of day.)

Having given both camps a good airing and after saying “It depends on how you think of a handle,” I will attempt to sidestep the issue for the rest of the book. In the end, it isn’t important – what is important is that you understand that passing a handle allows the caller’s object to be changed unexpectedly.

本文固定链接: http://www.chepoo.com/java-value-passed-and-passed-by-reference.html | IT技术精华网

【上一篇】
【下一篇】

Java值传递与引用传递:等您坐沙发呢!

发表评论