我有一个采用多个参数的方法,其中一些参数将在方法内部进行更改。有些用作只读。客户端(调用此类方法的代码的其他部分)将对象实例作为参数提供。
有哪些java语言结构可以让我声明一个参数不应该或者不会被激活或者不能在方法内变异。类似于注释或关键字的构造,告诉客户端该方法不会更改在方法调用中用作参数的对象实例。此外,如果我(作为这种方法的实现者)试图在方法实现中意外地改变对象,那么会产生编译错误或警告的构造。
我知道关键字final
,但这只是为了确保不更新引用。
不变性不是解决方案,就像在其他方法(或我的应用程序中的其他地方)一样,我希望类型的实例是可变的,只有在这个方法调用中,我想给出一个"承诺&#34 ;对于客户来说,我不会改变他作为论据提供的实例。
深度复制或克隆参数或让客户端(调用者)执行此类操作不是必需的,因为它不是方法逻辑的一部分,无论如何都要更改实例。我只是想知道这种语言是否有助于仔细检查这种情况是否会发生。
答案 0 :(得分:4)
没有办法将参数定义为只读(只是你已经提到的)。但是,您可以使用builder pattern来构建传递的对象,以便构建的对象只有getter方法,因此它不会有setter方法使其有效地不可变(注意,反射仍然可以用于修改其字段)。
答案 1 :(得分:3)
您正在寻找 immutability 。 final
确保无法更新引用,但仍可以更改可变字段。通过创建类 immutable 的实例,可以确保实例的值永远不会更改。
检查strategy for defining immutable Objects
如果您不想让实例不可变,您仍然可以通过传递防御性副本来保证客户端提供的对象不会发生变化 / 深度复制的实例。
答案 2 :(得分:3)
那里没有适合您的纯Java解决方案。
正如您所提到的,Parse.Cloud.afterSave("_User", function(request, response) {
if (!request.object.existed()) {
// Set default values
console.log("User did not yet exist")
var RunnerClass = Parse.Object.extend("Runner");
var runner = new RunnerClass;
runner.set("username", request.object.get("username"));
runner.set("userId", request.object.id);
runner.save()
} else {
console.log("User exists")
}
})
关键字只会确保不能为该引用分配新值。
您可以使用的一个预防措施是根据具体情况克隆或包装您的可变参数。
有一些(繁琐的)技术可用于深度克隆集合和地图(有关SO中的快速示例,请参阅here和here)。
最终,一个精心呈现的全面的javadoc可以在这里提供适当级别的文档。