gpt4 book ai didi

Java 总是按值传递,那么为什么我在使用 Array.get(index) 时会得到引用?

转载 作者:行者123 更新时间:2023-12-01 17:41:38 24 4
gpt4 key购买 nike

我正在解决我的应用程序中的这个错误,并看到一些非常奇怪的东西:

    selectedService = dataResponse.getServices().get(position);
selectedService.setPrice(3000);
dataResponse.getServices().get(position).getPrice(); // Returns 3000 which should be 0

get方法不应该将对象复制到selectedService中吗? ?如果没有怎么复制?

最佳答案

不,不应该。

Java 总是按值传递,但该值本身就是一个引用。因此,如果您调用更改该特定对象的数据的方法,它将反射(reflect)到从该特定对象检索数据的所有方法。

此问题的一个可能的解决方案是使 immutable types 。有些类已经实现了这一点,例如,java.time 包中的所有类都是不可变的。这些类的所有“setter”都会返回实例的新副本,并设置指定的值。一个例子可能是 LocalDate::plusDays .

<小时/>

这里有一个小例子,说明了按值传递和按引用传递之间的区别。

看一下这段代码。

void main() {
Dog myLittleDog = new Dog("Brutus");
change(myLittleDog);
System.out.println(myLittleDog.getName());
}

void change(Dog aDog) {
aDog = new Dog("Jack");
}

这里发生了什么?我们将名为“Brutus”的狗传递给 change 方法。在此方法中,我们用名为“Jack”的新狗替换了 Brutus。如果我们打印 myLittleDog 的名字,他的名字是什么?会是“ jack ”吗?
答案是否定的。对狗的引用的值被复制,并且可以在名称 aDog 下的 change 方法中使用。 myLittleDogaDog 都引用内存中同一个实际的狗对象。但现在 change 方法用 new 对象重新分配 aDog 。此时,变量 myLittleDogaDog 都引用不同的对象。一旦 change 方法退出,变量 aDog 将无法访问,并且 Jack 会被垃圾回收。 myLittleDog 仍被称为“Brutus”。

相反,如果 Java 是按引用传递的,情况就不会如此。那么,aDog 的重新分配也意味着 myLittleDog 的重新分配。

另请参阅:What's the difference between passing by reference vs. passing by value?

但是为什么我的 selectedService 仍然发生了变化?

虽然引用的值在传递给方法时会被复制,但这并不意味着对象不能更改(即不能修改)。假设我给你一份我家 key 的副本。你进入我的房子并将沙发移到厨房。然后,如果我进入我的房子,我会看到沙发已经被移动了。引用值被复制,但访问引用对象(房屋)的每个人都会看到对其进行的修改。

关于Java 总是按值传递,那么为什么我在使用 Array.get(index) 时会得到引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60392187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com