java中的不可修改列表

use*_*325 12 java list arraylist unmodifiable

我试图设置一个List不可修改的.

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

不应修改此列表,但我不想捕获unmodifiableList返回的异常.

private List<T> listeReferenceSelectAll = null;
List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;
return new ArrayList<T>(oListeRet);
Run Code Online (Sandbox Code Playgroud)

它是一个现有的代码,我必须将其转换为返回一个不可修改的列表,但是如果调用了"add"方法,则不必捕获任何异常.

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

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

duf*_*ymo 64

你需要java.util.Collections:

return Collections.unmodifiableList(oListeRet);
Run Code Online (Sandbox Code Playgroud)

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


Ach*_*Jha 19

Collections.unmodifiableList

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


Ant*_*iuc 7

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)
Run Code Online (Sandbox Code Playgroud)

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


Ale*_*iev 6

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

1)吞下例外的总体意图与"快速失败"原则相矛盾.他们没有及早发现和捕捉缺陷,而是被允许"在地毯下"变成时间炸弹.

2)不投掷UnsupportedOperationException是直接违反List合同的,其中说:

Throws:
    UnsupportedOperationException - if the add method is not supported by this list.
Run Code Online (Sandbox Code Playgroud)

所以对问题标题中写的内容的正确答案:"java中的不可修改的列表"应该仍然是:

return Collections.unmodifiableList(oListeRet);
Run Code Online (Sandbox Code Playgroud)


Adi*_*tya 5

如果绝对必须这样做,请尝试遵循所创建列表中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
    }
}
Run Code Online (Sandbox Code Playgroud)

在同一行上添加您需要的任何其他方法。只需确保覆盖了所有可能在您的代码中用于修改的构造函数和方法,以确保该列表不可修改。

使用Collections API是一种更干净,更好的方法,因此仅在使用Collections.UnmodifiableList无法满足您的需要时才使用此方法。

请记住,这将是调试时的噩梦,因此请尽可能多地记录日志。

  • 因此,您将通过添加更多错误代码来使问题复杂化?并且请指出“不良影响”?与添加更多错误代码相比,这些危害如何? (5认同)
  • @ user2346325,当其他所有人列出正确的“官方”方式时,您将无法认真接受此答案! (3认同)