17

我正在尝试设置一个List不可修改的。

在我的代码中,我有一个返回列表的方法。

这个列表不应该被修改,但我不想捕获 unmodifiableList 返回的异常。

private List<T> listeReferenceSelectAll = null;
List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;
return new ArrayList<T>(oListeRet);

这是一个现有代码,我必须对其进行转换以返回一个不可修改的列表,但如果调用了“add”方法,则不必捕获任何异常。

首先,我创建了一个实现 List 以覆盖“add”方法来记录异常而不是捕获它的类。

但我不知道如何正确实例化它......

4

7 回答 7

72

你需要java.util.Collections

return Collections.unmodifiableList(oListeRet);

如果您必须自己编写,请让该类实现List接口并为修改内容的方法抛出异常。

于 2013-05-03T09:59:48.053 回答
22

Collections.unmodifiableList

返回指定列表的不可修改视图。此方法允许模块为用户提供对内部列表的“只读”访问权限。对返回列表的查询操作“通读”到指定列表,并尝试修改返回的列表,无论是直接还是通过其迭代器,都会导致 UnsupportedOperationException。如果指定的列表是可序列化的,则返回的列表将是可序列化的。同样,如果指定的列表执行,则返回的列表将实现 RandomAccess。

于 2013-05-03T09:59:51.440 回答
10

Java-9提供了一种创建不可修改/不可变 List的新方法:

jshell> List<Integer> list = List.of(1,2,3);
list ==> [1, 2, 3]

jshell> list.add(10);
|  java.lang.UnsupportedOperationException thrown: 
|        at ImmutableCollections.uoe (ImmutableCollections.java:70)
|        at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:76)
|        at (#6:1)

List.of创建一个包含任意数量元素的不可变列表。

于 2017-03-11T21:21:52.917 回答
8

尽管接受的答案解决了省略/吞下 . 的要求UnsupportedOperationException,但应该解释为什么这是一种不受欢迎的做法。

1) 吞下异常的总体意图与“快速失败”原则相矛盾。他们没有及早发现和发现缺陷,而是被允许“躲在地毯下”变成定时炸弹。

2) 不投掷UnsupportedOperationException直接违反了List's 的合同,该合同规定:

Throws:
    UnsupportedOperationException - if the add method is not supported by this list.

因此,对问题标题中所写内容的正确答案:“Java 中的不可修改列表”仍然应该是:

return Collections.unmodifiableList(oListeRet);
于 2015-03-28T09:54:35.267 回答
4

如果您绝对必须这样做,请尝试遵循您正在创建的列表中 java.util.List指定的协定。

你的代码看起来像

public class UnmodifiableArrayList<E>  extends ArrayList<E> {

    public UnmodifiableArrayList(Collection<? extends E> c) {
        super(c);
    }

    public boolean add(int index) {
        return false;//Returning false as the element cannot be added 
    }

    public boolean addAll(Collection<? extends E> c) {
        return false;//Returning false as the element cannot be added 
    }

    public E remove(int index) {
        return null;//Returning null as the element cannot be removed
    }
}

在同一行添加您需要的更多方法。只需确保代码中可能用于修改的所有构造函数和方法都被覆盖,以确保列表不可修改。

使用 Collections API 是一种更简洁、更好的方法,因此只有在使用 Collections.UnmodifiableList 不能满足您的需要时才使用这种方法。

请记住,调试时这将是一场噩梦,所以尽可能多地记录。

于 2013-05-03T10:19:45.370 回答
2

1)这些行没有意义

List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;

2) 使用 Collections.unmodifiableList。

return Collections.unmodifiableList(oListeRet);

您不需要捕获它可能抛出的异常,它们都是 UnsupportedOperationException - RuntimeExceptions

于 2013-05-03T10:03:27.030 回答
-1

关于不可修改列表的评论是正确的。创建一个调用 Collections.unmodifiableList 的方法访问器。但是,您可能只想使用这样的数组,并在内部使用列表。

 public MyObject[] getObjects() {
    return (MyObject[]) mList.toArray();
 }
于 2016-06-05T17:26:50.493 回答