有没有办法在Java中实现类似于C ++的const
的东西?具体来说,我有一个像
private static Vector2 sum(Vector2 vec1, Vector2 vec2) {
return vec1.cpy().add(vec2);
}
我想要
现在我知道java严格按引用传递(我只是戏弄,当然我知道it is pass-by-value or rather pass-by-copying-a-reference)。我的意思是,在Java中,当您调用方法时,将复制引用,但该引用指向相同的对象内容。如果类具有公共字段或setter,则被调用的方法始终可以修改传递的对象的内容。有没有例如像@NotNull
这样的注释或防止这种情况的工具?我刚刚找到了像@Contract(pure = true)
这样的JetBrains注释,但我认为它们不提供任何检查。
答案 0 :(得分:3)
您无法保证该方法不会更改参数。如果要避免更改对象,则应使其不可变。您可以使用一些包装类在内部传递,而不提供setter。或者你可以让你的setter包本地,并在你需要调用一些package-local方法时在同一个包中使用一些访问助手类。
答案 1 :(得分:2)
您可以在参数中添加final
,但这只会阻止初始化,您仍然可以调用方法和设置器来修改Vector
的内容。
如果您需要限制对这些内容的访问权限,则可能需要创建隐藏Vector
,包装器的不可变类。基本上,它将仅通过隐藏setter来重定向阻止任何更新的方法,并将getter限制为原始值,返回实例可以更改其中的值。
当然,也有一些激烈的解决方案,你可以克隆 Vector及其内容。即使有人试图更新某些值,也能保证实例安全。这只会在此调用期间出现问题,使用错误的值但会保持原始实例不变。
或者您可以使用这两种解决方案,创建一个返回克隆实例的包装器(只需要提供一个返回克隆的get(int索引))。此解决方案是内存消耗(仅克隆所需实例)和限制性getter之间的折衷。
答案 2 :(得分:1)
在Java中,唯一的方法是使用只读接口和可变接口。这不容易维护,const
会更好,但它不可用。你可以写
interface ReadOnlyVector<T> {
int size();
// getter methods
T get(int n);
default ReadOnlyVector<T> add(ReadOnlyVector<T> v) {
// add two vectors are create a new one.
}
}
interface Vector<T> extends ReadOnlyVector<T> {
// mutating methods.
void add(T t);
}