当前位置: 首页 > 面试题库 >

Java怀疑中通过引用传递

越高峻
2023-03-14
问题内容

因此,我正在阅读这篇文章,并没有回复。2.在该示例中,调用该方法后,地址42处的Dog值是否更改为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通过值传递- 始终 为基元和对象传递值。

就对象而言,传递的是对存在于堆中的对象的引用。当传入引用时,方法不能更改该引用所指向的内容。

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

摘自Ken Arnold和James Gosling撰写的“ Java编程语言第二版”(ISBN
0-201-31006-6)(可能来自第40页-现在暂时没有书):

有人会错误地说Java对象是“按引用传递”。术语“按引用传递”正确地表示,当将参数传递给函数时,调用的函数将获得对原始值的引用,而不是其值的副本。如果函数修改了其参数,则调用代码中的值将被更改,因为参数和参数使用内存中的同一插槽。[…]
Java中只有一种ParameterPassing模式(按值传递),这有助于使事情变得简单。

因此,让我们看一下您的示例(进行一些改进):

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退出时有资格进行垃圾回收。

指向“流动站”的传入引用具有可变的数据成员:其名称。在AAA行更改其值将反映在传入的引用中。因此输出不同。



 类似资料:
  • 问题内容: 这两个代码有什么区别: 代码A: 哪里 VS. 代码B: 这两个代码之间有什么区别吗? 问题答案: Java始终按值传递参数,而不按引用传递参数。 让我通过一个例子解释一下: 我将逐步解释这一点: 声明一个名为ftype 的引用,Foo并将其分配给Foo具有属性的type的新对象”f”。 从方法方面,声明Foo具有名称的类型引用,a并将其初始分配给null。 调用方法时changeRe

  • 问题内容: 是否可以通过Java通过引用传递对象 就像在C#中一样 问题答案: 不,这在Java中是不可能的。 在Java中,方法的所有参数均按值传递。注意非原始型的的变量,它们是对对象的引用,也由值来传递:在这种情况下, 参考 是 由值来传递 。请注意,按值传递引用与按引用传递不同。

  • 问题内容: 我习惯在中执行以下操作: 输出为: 但是,在Java中,这似乎不起作用。我认为是因为该对象是复制的,而不是通过referenced传递的。我以为字符串是对象,总是通过引用传递。 这里发生了什么? 问题答案: 你有三种选择: 使用StringBuilder: 创建一个容器类,并将容器的实例传递给你的方法: 创建一个数组: 从性能的角度来看,StringBuilder通常是最佳选择。

  • 问题内容: 您可以使用关键字“ ref”在.NET中进行操作。用Java有什么办法吗? 问题答案: 您正在用自己的方法做什么?如果仅填充现有数组,则不需要.NET或Java中的按引用传递语义。在这两种情况下,引用都将按值传递-因此对 对象的 更改将由调用者看到。这就像告诉某人您的住所地址,并要求他们向其提供物品-没问题。 如果您 确实 需要传递引用语义,即调用方将看到对参数本身所做的任何更改,例如

  • 问题内容: 这个问题已经在这里有了答案 : 8年前关闭。 可能重复: Python范围规则的简短描述 我写了两个简单的函数: 相比之下,在之后赋值,然后引发Exception:,我认为当我调用inner时,var的值为2,我错了吗? 问题答案: 是的,您在这里不正确。函数定义引入了新的范围。