在Java疑惑中通过引用传递 [英] passing by reference in Java doubts

查看:135
本文介绍了在Java疑惑中通过引用传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在阅读这篇文章和回复号。 2.在该示例中,在调用该方法之后,Dog值是否在地址42处,名称的更改为Max?

So I was reading this post and response no. 2. In that example, after calling that method, does the Dog value at address 42, name's changes to Max?

Dog myDog;

Dog myDog = new Dog("Rover");
foo(myDog);

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}


推荐答案

Java传递按值 - 总是,对于基元和对象都是。

Java is pass by value - always, both for primitives and objects.

对于对象,传递的东西是对象的引用生活在堆里。方法无法更改引用传入时引用的内容。

In the case of objects, the thing that's passed is the reference to the object that lives out on the heap. A method cannot change what that reference points to when it's passed in.

如果该引用指向具有可变数据的对象,则该方法可以更改其状态。

If that reference points to an object that has mutable data, the method can alter its state.

来自Java编程语言第二版,由Ken Arnold和James Gosling撰写(ISBN 0-201-31006-6)(可能来自第40页 - 没有这本书现在很方便):

From "The Java Programming Language Second Edition", by Ken Arnold and James Gosling (ISBN 0-201-31006-6 ) (probably from page 40--don't have the book handy right now):


有些人会错误地说Java中的对象是通过
引用传递。术语传递正确意味着当
参数传递给函数时,调用的函数获得对原始值的
引用,而不是其值的副本。如果
函数修改了它的参数,则调用代码中的值将变为
,因为参数和参数在
内存中使用相同的插槽。 [...] Java中只有一个ParameterPassing模式 - 按值传递
- 这有助于简化操作。

Some people will say incorrectly that objects in Java are "pass by reference." The term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory. [...] There is exactly one ParameterPassing mode in Java--pass by value--and that helps keep things simple.

那么让我们来看看你的例子(有一些改进):

So let's look at your example (with some improvements):

public class Dog {

    private String name;

    public static void main(String [] args) {
        Dog myDog = new Dog("Rover");
        System.out.println("before foo: " + myDog);
        foo(myDog);
        System.out.println("after  foo: " + myDog);
    }

    public static void foo(Dog someDog) {
        someDog.setName("Max");     // AAA
        someDog = new Dog("Fifi");  // BBB
        someDog.setName("Rowlf");   // CCC
    }

    public Dog(String n) { this.name = n; }

    public String getName() { return this.name; }

    public void setName(String n) { this.name = n; }

    public String toString() { return this.name; }
}

这是输出:

before foo: Rover
after  foo: Max

Tool completed successfully

您无法更改传递给 foo 的引用指向的内容,因此将其设置为引用BBB行的名称Fifi,随后在CCC行更改该对象的名称,什么都不做。当 foo 退出时,该实例有资格进行垃圾收集。

You can't change what the reference that's passed to foo points to, so setting it to the reference with the name "Fifi" at line BBB, and subsequently changing the name of that object at line CCC, does nothing. That instance is eligible for garbage collection when foo exits.

指向Rover的传入引用具有可变数据成员:其名称。在AAA行更改其值会反映在传入的引用中;因此产出不同。

The incoming reference that points to "Rover" has a mutable data member: its name. Changing its value at line AAA is reflected in the reference that was passed in; hence the different output.

这篇关于在Java疑惑中通过引用传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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