我一直以为Java参照传递。
然而,我看到了一些博客文章声称事实并非如此。
我想我不明白他们的区别。
原因是什么?
发布于 2018-05-28 10:06:10
Java总是按值传递。不幸的是,他们决定将对象的位置称为“引用”。参照系对初学者来说这很混乱。
事情是这样的:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true, java passes by value
aDog.getName().equals("Fifi"); // false
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
在上面的例子中aDog.getName()
还会回来"Max"
。价值aDog
内main
函数中未更改。foo
带着Dog"Fifi"
因为对象引用是通过值传递的。如果它是通过引用传递的,则aDog.getName()
在main
会回来"Fifi"
在打电话到foo
。
同样:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
在上面的例子中,Fifi
是狗在呼叫后的名字吗?foo(aDog)
的内部设置了对象的名称。foo(...)
。任何行动foo
执行d
是这样的,为了所有实际的目的,它们都是在aDog
本身(除非d
被更改为指向另一个Dog
例如d = new Dog("Boxer")
)。
发布于 2018-05-28 10:42:08
Java规范指出,Java中的所有东西都是按值传递的.在Java中没有所谓的“通过引用传递”的东西。
理解这一点的关键是
Dog myDog;
Dog myDog = new Dog("Rover");
foo(myDog);
你实际上是在通过地址被创造的Dog
对象的foo
方法。
假设Dog
对象驻留在内存地址42。这意味着我们将42传递给方法。
如果方法被定义为
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
someDog
设置为值42。someDog
被跟踪到Dog
它指向(Dog
对象位于地址42)Dog
(地址42的那个)被要求将他的名字改为Max。
Dog
被创造了。假设他在地址74someDog
至74
Dog
它指向(Dog
对象位于地址74)Dog
(地址74的人)被要求将他的名字改为Rowlf。现在,让我们考虑一下在方法之外发生了什么:
做myDog
换衣服?
记住myDog
是指针,而不是真的Dog
答案是否定的。myDog
仍然有值42;它仍然指向原始Dog
(但请注意,由于“AAA”行,它的名字现在是“MAX”-仍然是同一只狗;myDog
)其值没有变化。)
它完全适用于跟随一个地址,并更改它末尾的内容;但是,这不会改变变量。
Java的工作方式与C完全一样。可以分配指针,将指针传递给方法,遵循方法中的指针,并更改指向的数据。但是,不能更改指针指向的位置。
在C+、Ada、Pascal和其他支持按引用传递的语言中,实际上可以更改传递的变量。
如果Java具有通过引用传递的语义,则foo
方法将更改myDog
当它被分配给someDog
在线BBB。
将引用参数视为传入变量的别名。当指定别名时,传入的变量也是如此。
https://stackoverflow.com/questions/-100004551
复制相似问题