question的延续。
我需要将静态和公开存储数据作为数组,但我不希望有人修改我的数据。我只需要从这些数组中读取数据。因此我认为我应该使用C ++中提供的常量数组之类的东西。
据我所知Collections.unmodifiableList(Arrays.asList(...))
阻止在运行时修改列表,但不能在编译时修改列表。
我已经完成了以下课程(代码已更新)。我想我没有重新发明轮子因为我使用unmodifiableList
得不到相同的结果。
/**
* Emulates constant arrays from C++.
*
* @param <E> Type of elements. Has to be immutable type.
*/
public final class ConstArray<E> {
/** Stores elements. */
private final E[] storage;
/**
* Constructs the object.
*
* @param storage Elements.
*/
public ConstArray(final E[] storage) {
this.storage = storage.clone();
}
/**
* Returns element at {@code idx}.
*
* @param idx Index of returning element.
* @return Element at {@code idx}.
*/
public final E get(final int idx) {
return storage[idx];
}
}
省略size
方法和其他一些方法。
我已经对课程进行了测试,但它确实有效。
要解释一下,如果我提供我的图书馆并且有人试图修改我的数据,我认为当他/她立刻知道它不可能时会更好(我的班级不会这样做)有一个方法来修改任何东西)如果我使用unmodifiableList
他/她将注意到程序崩溃。
这门课的优点和缺点是什么?有没有办法改善这个班级?
我决定使用@Hoopje的建议(见答案)。它基于我没有的经验:我只是一个Java初学者。
答案 0 :(得分:2)
如果“重新发明轮子”不够缺点,我认为你的方法有一个主要的缺点:
Arrays.asList
和Collections.ummodifiableList
返回List
个实例,因此它们集成在Java Collections框架中。这意味着您可以在增强型for循环(for (E item : list) { }
)中轻松使用它们,作为流(list.stream()
),使用所有List
方法,将它们传递给期望Collection
的方法或List
子类等。
一个小问题是,您的类会复制数组,而Arrays.asList
和Collections.ummodifiableList
都会返回其参数的视图,因此它们不会复制数组。
顺便说一下,创建数组的浅表副本不需要“魔术”:你可以做
this.storage = storage.clone();
回答UPD1:
是的,遗憾的是Java没有为无法修改的集合提供接口。因此,不可变的List
实例将具有例如仅抛出异常的add(E)
方法。因此,不存在编译时保证不变性。
但是,在您的方法的Javadoc中,您当然会写出返回的列表是不可变的。如果您的图书馆用户测试他/她的软件,他将非常确定地看到异常并意识到他/她编程错误。
相信我,你的图书馆用户会非常讨厌你,如果你拿走他们在基于收集的API中使用返回列表的可能性,只是因为没有任何方法看起来好像他们会修改它。