Ste*_*ker 8 java pass-by-reference pass-by-value
我在这里阅读这篇评论:在Java中通过引用传递字符串?
是的,这是一种误解.这是一个巨大而广泛的误解.这导致我讨厌的一个采访问题:("Java如何传递参数").我讨厌它,因为大约一半的采访者实际上似乎想要错误的答案("基于价值的原语,通过引用的对象").正确的答案需要更长的时间,而且似乎会混淆其中一些.并且他们不会被说服:我发誓我在技术屏幕上不及格,因为CSMajor型筛选者在大学里听到了误解,并认为它是福音.FEH. - CPerkins于2009年8月13日14:34
有人可以解释一下,新程序员可以掌握,说:
"在Java中,原语通过值传递,对象通过引用传递."
和:
"在Java中,没有任何内容通过引用传递,引用按值传递."?
这些陈述在某种意义上都是真的吗? 我不想邀请咆哮游行,但这听起来像一个非常重要的概念,而我仍然不完全理解.
aio*_*obe 12
我认为错误观念在于变量不能包含一个开头的对象.如果你掌握了这一点,那么显然变量只能包含对象(或原始值)的引用.从那里开始实现引用按值传递的步骤(就像原始值一样)非常小.
您可以通过一个非常简单的测试来确定语言是否支持通过引用传递.问问自己是否可以用语言编写交换函数,即类似的东西
x == A, y == B
swap(x, y);
x == B, y == A
Run Code Online (Sandbox Code Playgroud)
作为一个Java程序员,你很快意识到,你不能在Java中实现这一点,所以你(正确地)得出Java没有结论不参照具有通.
回到你的句子:
这是错误的.我认为你只能传递一个包含在变量中的东西,正如我上面所说的,变量不能包含一个对象,因此你无法在Java中传递一个对象.
这是事实.
这样的事情在绘制时总是更容易.考虑以下两个变量,一个是基本类型,另一个是引用类型:
int i = 5;
String s = "test";
Run Code Online (Sandbox Code Playgroud)
在内存中的某个地方有一个条目i,如下所示:
i
-----
| 5 |
-----
Run Code Online (Sandbox Code Playgroud)
类似地s,内存中也有一个条目,但它引用堆上的位置,因为它s是一个引用类型变量,并且对象存储在堆上:
-----------
s |------->| "test" |
----- | |---------|
| --|--------------| | |
----- | |
| |
|---------|
Run Code Online (Sandbox Code Playgroud)
所以值s是对位于堆上的String对象的引用,所以如果s传递给方法:
printString(s);
public void printString(String arg)
{
System.out.println(arg);
}
Run Code Online (Sandbox Code Playgroud)
实际复制到arg参数中的值是s对堆上的引用:
-----------
s |------->| "test" |<-----|
----- | |---------| |
| --|--------------| | | |
----- | | |
| | |
|---------| |
arg |
----- |
| --|-----------------------------------------
-----
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
好问题.请考虑以下示例
void foo(Object obj) {
obj = new Foo();
}
Run Code Online (Sandbox Code Playgroud)
Object o = new Bar();
foo(o);
// is o Foo or Bar?
Run Code Online (Sandbox Code Playgroud)
pass by-reference该o参考可能已经改变后调用foopass by-reference-by-value参考o没有改变foo