Collections.unmodifiableList(Arrays.asList(...)) 的替换

Replacement for Collections.unmodifiableList(Arrays.asList(...))

question.

的延续

我需要静态公开将数据存储为数组,但我不需要希望有人修改我的数据。我只需要能够读取这些数组。因此,我认为我应该使用 C++ 中提供的 constant arrays 之类的东西。

据我了解,Collections.unmodifiableList(Arrays.asList(...)) 阻止在 运行-time 修改列表,但在 compile-time.

我做了以下 class(代码已更新)。我想我 不是重新发明轮子 因为我无法使用 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方法和其他一些方法

我测试了 class 并且它有效。

换句话说,如果我提供了我的库并且有人试图修改我的数据,我认为当 he/she 立即知道这是不可能的时候会更好(我的 class 没有方法来修改任何东西),如果我使用 unmodifiableList he/she 只会注意到程序崩溃。

这个class的优缺点是什么?有没有办法改进这个class?

更新:

我决定采纳@Hoopje 的建议(查看答案)。它基于我没有的经验:我只是一个 Java 初学者。

如果 "reinventing the wheel" 还不够不利,我认为您的方法有一个主要缺点:

Arrays.asListCollections.ummodifiableList return List 实例,因此它们集成在 Java 集合框架中。这意味着您可以轻松地在增强的 for 循环 (for (E item : list) { }) 中使用它们,作为流 (list.stream()),使用所有 List 方法,将它们传递给需要 Collection 的方法或 List subclasses 等

一个小问题是你的 class 复制了数组,而 Arrays.asListCollections.ummodifiableList return 观点都是他们的论点,所以他们没有复制数组。

顺便说一下,创建一个数组的浅拷贝不需要"magic":你可以做到

this.storage = storage.clone();

对 UPD1 的回答:

是的,不幸的是 Java 没有为无法修改的集合提供接口。因此,不可变的 List 实例将有一个 add(E) 方法,它只是抛出一个异常。所以没有编译时不变性保证。

但是,在您的方法的 Java 文档中,您当然会写 returned 列表是不可变的。如果您的库的用户测试 his/her 软件,他将非常确定地看到异常并意识到 he/she 出现了编程错误。

相信我,如果你剥夺了他们在基于集合的 API 中使用 returned 列表的可能性,你的图书馆的用户会非常讨厌你,只是为了没有任何的小优势看起来好像会修改它的方法。