首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java是“按引用传递”还是“按值传递”?

Java是“按引用传递”还是“按值传递”?
EN

Stack Overflow用户
提问于 2018-05-28 01:36:02
回答 2查看 0关注 0票数 0

我一直以为Java参照传递

然而,我看到了一些博客文章声称事实并非如此。

我想我不明白他们的区别。

原因是什么?

EN

回答 2

Stack Overflow用户

发布于 2018-05-28 10:06:10

Java总是按值传递。不幸的是,他们决定将对象的位置称为“引用”。参照系对初学者来说这很混乱。

事情是这样的:

代码语言:txt
复制
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"。价值aDogmain函数中未更改。foo带着Dog"Fifi"因为对象引用是通过值传递的。如果它是通过引用传递的,则aDog.getName()main会回来"Fifi"在打电话到foo

同样:

代码语言:txt
复制
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"))。

票数 0
EN

Stack Overflow用户

发布于 2018-05-28 10:42:08

Java规范指出,Java中的所有东西都是按值传递的.在Java中没有所谓的“通过引用传递”的东西。

理解这一点的关键是

代码语言:txt
复制
Dog myDog;
代码语言:txt
复制
Dog myDog = new Dog("Rover");
foo(myDog);

你实际上是在通过地址被创造的Dog对象的foo方法。

假设Dog对象驻留在内存地址42。这意味着我们将42传递给方法。

如果方法被定义为

代码语言:txt
复制
public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}
  • 参数someDog设置为值42。
  • 在“AAA”线上
    • someDog被跟踪到Dog它指向(Dog对象位于地址42)
    • Dog(地址42的那个)被要求将他的名字改为Max。

  • 在“BBB”行
    • 新的Dog被创造了。假设他在地址74
    • 我们指定参数someDog至74

  • 在“CCC”行
    • 有人跟着狗到了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。

将引用参数视为传入变量的别名。当指定别名时,传入的变量也是如此。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档