不变性如何确定Java方法是否修改作为参数传递的对象
我来自C++背景,目前正在学习java。当我尝试使用一些第三方库时,出现了一个问题。如何确定对以对象引用为参数的方法的调用是否会修改对象? 在C++中,这要通过使用const关键字来实现。如果方法签名为:void foo(Boo& boo);
我知道引用的对象可能会被修改,而如果方法签名是:
void foo(const Boo& boo);
编译器保证引用的对象不会被修改
我在Java中没有看到类似的东西,因为只有引用本身可以被声明为final,而不是被引用的对象,而且final参数在一开始就没有多大意义,因为它是通过值传递的。因此,当我看到一种方法,比如:
void foo(Boo boo) {...}
如何确定boo引用的对象是否在函数体中被修改(可能使用注释)?如果没有办法知道,是否有一些广泛使用的惯例或最佳实践来避免混淆和错误
# 1 楼答案
唯一的办法就是读代码
常见的约定是传递一个不能修改的对象,如果需要,可以使用包装器。这将确保类无法修改对象
如果对象是可克隆的,也可以使用
clone()
,但另一种常见的方法是使用副本如果您关心这种行为,单元测试可以显示方法是否修改对象。如果已经有了单元测试,通常需要额外检查一两行
# 2 楼答案
正如大家所说,更喜欢使用不可变对象,同时也避免使用无效方法
这种方法的可用目的
是更改对象本身的状态,还是更改作为参数传递的对象
# 3 楼答案
注意:这个答案是
它可以在编译时通过注释检查的各种东西中有Checker Framework就是IJG Immutablity checker。此检查器允许您使用^{} 或^{} 注释对象引用
问题是你经常不得不自己动手。为了简化任务,检查器框架可以automatically infer部分注释;你仍然需要自己做很多事情