java参数传递时到底是值传递还是引用传递(baidu搜集)
最近比较长一段时间以来,网上的IT同行里面比较流行“JAVA面试32问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解。
原题是:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
用google查询结果,得到答案基本上是:值传递。当时觉得挺纳闷儿,为什么连参数的内容都被修改了,怎么还能说是“值传递”呢?因为在传统的印象里(尤其是从C++过来以后),值传递都应该是不改变原参数的。
问问周围的同事,也大都这么讲,但是也都讲不清这种理论的根源是什么。我这个人有个毛病,有事情想不通时就会憋得难受,后来在《Thinking in Java》的一段内容(注解[1])里找到了自己的结论,我认为(《Thinking in Java》的作者也这么认为):可以说是值传递,也可以说是引用传递。
一,认为是值传递。得出这种结论的前提必须是“参数的值就是对该对象的引用,而不是对象的内容”,这句话可能有些费解,举个例子加以说明。
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 don’t 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 that important – what is important is that you understand that passing a handle allows the caller’s object to be changed unexpectedly.
相关推荐
Java中参数传递的方式有两种理解:值传递和引用传递,但这两种说法实际上是对同一种机制的不同角度的描述。下面将详细解释这两种理解方式。 首先,我们来看值传递的理解。在Java中,当一个对象作为参数传递给方法时...
无论将Java的参数传递称为"值传递"还是"引用传递",重要的是要明白对象的引用不会改变,但对象的内容可以在方法中被修改。这种机制使得Java的代码更安全,避免了不必要的副作用,同时也提供了灵活的编程模型。
在Java编程语言中,关于参数传递的方式一直存在两种观点:一种认为Java仅支持按值传递,另一种则指出Java同时支持按值传递和按引用传递。实际上,这两种观点并非完全对立,而是根据不同的角度来描述Java中的参数传递...
13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递....
在Java编程语言中,函数参数的传递方式有两种:值传递和引用传递。理解这两种机制对于编写高效、无误的代码至关重要。以下是对这两种传递方式的详细解析。 首先,值传递是指函数调用时,实际参数的值被复制一份传给...
在Java编程语言中,了解值传递和引用传递的概念至关重要,因为它们直接影响到函数参数的处理方式。下面将详细探讨这两个概念及其区别。 首先,我们来理解什么是值传递。在Java中,基本数据类型(如int、double、...
11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java参数传递.zip11.java...
当讨论方法参数时,有两种术语经常被提及:值传递(Call by Value)和引用传递(Call by Reference)。Java参数传递的规则是:**Java只使用值传递,但这种值传递对于对象参数表现为类似引用传递的行为。** 在值传递...
58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递机制.zip58.java参数传递...
这里详细的说明了,java参数传递的过程,引用传递,值传递
在Java中,参数传递主要有两种方式:值传递(Value Passing)和引用传递(Reference Passing)。虽然Java官方文档并未明确提及引用传递,但Java中的对象实际上是以引用的方式进行传递。 首先,我们来看基本类型(如...
无论是基本类型还是对象类型,参数传递都是以值的形式进行,但对象类型的值是其引用,允许我们在方法内修改对象的状态,而不影响方法外部的引用。这种特性使得Java能够实现封装和数据安全性,同时也为程序员提供了...
Java中传递对象时传递的并不是对象中的内容, 而是对象的地址。
Java 中的参数传递机制是一个经久不息的讨论话题,究竟是“传值”还是“传引用”,双方各执一词,互不相让。本文将通过详细的分析和实例,揭开 Java 参数传递机制的奥秘。 基本类型作为参数传递 首先,我们来看...
Java 面向对象值传递和引用传递 Java 面向对象编程中,参数传递是非常重要的一个概念。参数传递有两种方式:值传递和引用传递。了解这两种方式的区别是非常重要的,因为它们对程序的执行结果产生了很大的影响。 值...
62.java引用类型的参数传递.zip62.java引用类型的参数传递.zip62.java引用类型的参数传递.zip62.java引用类型的参数传递.zip62.java引用类型的参数传递.zip62.java引用类型的参数传递.zip62.java引用类型的参数传递....
这意味着当你传递一个对象作为参数时,实际上是传递了对该对象的引用,而不是对象本身的副本。因此,在方法内部对这个对象所做的任何改变都会反映到原始对象上。 #### 四、参数传递示例 以下代码展示了如何在Java...
Java 语言中参数值传递和引用传递比较 Java 语言中参数值传递和引用传递是两种不同的参数传递方式,它们在 Java 编程中扮演着重要的角色。参数值传递是指将实际参数的值复制给形式参数,形式参数的变化不影响实际...