java - 如何确定 Java 方法是否修改了作为参数传递的对象

标签 java immutability

我有 C++ 背景,目前正在学习 Java。当我尝试使用一些第三方库时,出现了一个问题。如何确定对将对象引用作为参数的方法的调用是否修改了对象? 在 C++ 中,由于使用了 const 关键字,这一点很清楚。如果方法签名是:

void foo(Boo& boo);

我知道引用的对象可能会被修改,而如果方法签名是:

void foo(const Boo& boo);

编译器保证引用的对象不被修改。

我还没有在 Java 中看到类似的东西,因为只有引用本身可以声明为 final,而不是被引用的对象,并且 final 参数首先没有多大意义,因为它无论如何都是按值传递的。因此,当我看到这样的方法时:

void foo(Boo boo) {...}

如何确定 boo 引用的对象是否在函数体内被修改(可能使用注释)?如果没有办法知道,是否有一些广泛使用的约定或一些最佳实践来避免混淆和错误?

最佳答案

how do I determine if the object referenced by boo is modified inside the body of the function (maybe using annotations)?

不幸的是,唯一的方法是阅读代码。

If there is no way to know, is there some widely used convention or some best practices to avoid confusion and bugs?

通常的约定是传递一个无法修改的对象,如果需要,使用包装器。这确保类不能修改对象。

List<String> readOnly = Collections.unmodifiableList(list);

如果对象是可克隆的,您也可以使用clone(),但另一种常见的方法是使用副本。

List<String> readOnly = new ArrayList<>(list);

如果您关心此类行为,单元测试可以显示方法是否修改了对象。如果您已经进行了单元测试,通常需要一两行额外的代码来检查。

关于java - 如何确定 Java 方法是否修改了作为参数传递的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32164385/

相关文章:

Java:同步缓冲区

javascript - Selenium WebDriver : clicking a visible button inside a row of a table

go - 如何在 Go 中声明一个不可变变量?

java - Java 中不使用构建器模式的不可变字段

c# - 为什么 System.Windows.Point 和 System.Windows.Vector 是可变的?

object - 为什么 JVM GC 喜欢不可变对象(immutable对象)?

Python 方法 : modify original vs return a different object

java - ListView 内容问题(viewHolder 没有更改内部 View )

java - Neo4J SDN 4 无法保存

java - SpringBoot : Where to put internal container classes