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