Java 是“传递引用"吗?还是“传值"? [英] Is Java "pass-by-reference" or "pass-by-value"?

查看:27
本文介绍了Java 是“传递引用"吗?还是“传值"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直认为 Java 使用引用传递.

I always thought Java uses pass-by-reference.

然而,我看到一篇博文声称Java使用pass按值.

However, I've seen a blog post that claims that Java uses pass-by-value.

我不认为我理解他们的区别.

I don't think I understand the distinction they're making.

解释是什么?

推荐答案

Java 总是传值.不幸的是,当我们处理对象时,我们实际上是在处理称为引用的对象句柄,它们也是按值传递的.这种术语和语义很容易让许多初学者感到困惑.

Java is always pass-by-value. Unfortunately, when we deal with objects we are really dealing with object-handles called references which are passed-by-value as well. This terminology and semantics easily confuse many beginners.

事情是这样的:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // 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
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

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".main 中的值 aDogfoo 函数中没有改变,Dog Fifi" 因为对象引用是按值传递的.如果它是通过引用传递的,那么 main 中的 aDog.getName() 将在调用 后返回 Fifi"foo.

In the example above aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo with the Dog "Fifi" as the object reference is passed by value. If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.

同样:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // 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(...).food 上执行的任何操作,出于所有实际目的,它们都是在 aDog 上执行的,但不是 可以改变变量 aDog 本身的值.

In the above example, Fifi is the dog's name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog, but it is not possible to change the value of the variable aDog itself.

有关按引用传递和按值传递的更多信息,请参阅以下 SO 答案:https://stackoverflow.com/a/430958/6005228.这更彻底地解释了这两者背后的语义和历史,也解释了为什么 Java 和许多其他现代语言在某些情况下似乎两者兼而有之.

For more information on pass by reference and pass by value, consult the following SO answer: https://stackoverflow.com/a/430958/6005228. This explains more thoroughly the semantics and history behind the two and also explains why Java and many other modern languages appear to do both in certain cases.

这篇关于Java 是“传递引用"吗?还是“传值"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆