[英]How can i create a method that modifies an object of another class(java)?
[英]How to determine if a Java method modifies an object passed as parameter
我来自C ++背景,目前我正在学习Java。 当我尝试使用某些第三方库时出现了一个问题。 如何确定对作为参数的对象引用的方法的调用是否修改了对象? 在C ++中,由于使用了const关键字,因此很清楚。 如果方法签名是:
void foo(Boo& boo);
我知道引用的对象可能会被修改,而如果方法签名是:
void foo(const Boo& boo);
编译器保证不会修改引用的对象。
我没有在Java中看到类似的东西,因为只有引用本身可以被声明为final,而不是引用的对象,并且最终的参数在第一个地方没有多大意义,因为它无论如何都是通过值传递的。 因此,当我看到一个方法,如:
void foo(Boo boo) {...}
如何确定boo引用的对象是否在函数体内修改(可能使用注释)? 如果没有办法知道,是否有一些广泛使用的约定或一些最佳实践来避免混淆和错误?
如何确定boo引用的对象是否在函数体内修改(可能使用注释)?
唯一的方法是不幸地读取代码。
如果没有办法知道,是否有一些广泛使用的约定或一些最佳实践来避免混淆和错误?
常见的惯例是在需要时使用包装器传递无法修改的对象。 这样可以确保类无法修改对象。
List<String> readOnly = Collections.unmodifiableList(list);
如果对象是Cloneable,您也可以使用clone()
但另一种常见方法是使用副本。
List<String> readOnly = new ArrayList<>(list);
如果您关心此类行为,单元测试可以显示方法是否修改了对象。 如果您已经进行了单元测试,通常需要一两行来检查。
不幸的是,这种语言没有内置这种设施。 一个好的防御性做法是将您传递的数据对象定义为不可变的(即,没有任何允许修改其状态的公共方法)。 如果你真的关心这个问题,你可以在将对象传递给你不信任的方法之前复制/克隆一个对象,但这通常是一个多余的预防措施。
注意:这个答案是更详细的版本
在编译时可以通过注释检查的各种事物之间存在Checker Framework是IJG Immutablity检查器 。 此检查器允许您使用@Immutable
或@ReadOnly
注释对象引用。
问题是您经常需要自己注释库 。 为了简化您的任务,Checker Framework可以自动推断部分注释; 你仍然需要自己做很多事情。
如何确定boo引用的对象是否在函数体内修改(可能使用注释)?
我必须同意其他答案,没有直接的方法来确定该方法是否会修改您的对象,是的,以确保该方法无法修改您的Object
您必须做的就是在您身边。
如果没有办法知道,是否有一些广泛使用的约定或一些最佳实践来避免混淆和错误?
这里方法名称出现在场景中。 继续使用方法的命名约定,我们必须查看一些方法声明,这些声明明确地说服了您的Object
根本不会被更改。
例如,你知道Arrays.copyOf
不会改变你的实际数组, System.out.println(boo)
不会改变你的boo
方法名称是真正的武器 ,可以为方法用户提供尽可能多的信息。 (是的!这总是不可能,但要遵循相当不错的做法。)
让我们考虑在你的情况下说printBoo
只会打印, copyBoo
只会复制, clearBoo
会重置所有属性, checkAndCreateNewBoo
会检查你的boo
Object
并在需要时创建新的。
因此,最终,如果我们能以适当的方式调用者使用他们可以用事实放心Object
会调用该方法后保持不变。
正如大家所说,更喜欢使用不可变对象,也避免使用void方法
这样的方法的可用目的
void foo(Boo boo) {...}
是更改对象本身的状态或更改作为参数传递的对象
void completOrder(Order order) { ... }
//or
void parserTokenEnded(String str) { ... }
有一种方法,方法开发人员应将参数标记为final,如果它不打算修改参数。
public void test(final Object param)
然而,很少有人遵循这一点,因此很难知道。 然而,优秀的程序员遵循这条规则,尤其是编写api。 如果要编写方法并公开它。 make param final表示不会修改传递的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.