2017-03-15 136 views
0

我试图让一个不可修改的ArrayList到最后一个变量EX_FIELDS。 exList是一个现有的ArrayList对象。将一个ArrayList转换为一个不可修改的ArrayList

EX_FIELDS = (ArrayList<String>) Collections.unmodifiableList(exList); 

此代码出现在静态block.When类负载,我得到以下错误。

java.lang.ClassCastException: java.util.Collections$UnmodifiableRandomAccessList cannot be cast to java.util.ArrayList 

我需要使用EX_FIELDS支持随机access.Is有任何其他方式来完成它?感谢您的帮助提前

回答

8

EX_FIELDS应该有List<String>类型,而不是ArrayList<String>,你不该”吨需要做任何投:你应该只写

EX_FIELDS = Collections.unmodifiableList(exList); 

这是更普遍的规则,你应该改写为接口,而不是实现的一个实例。

+0

或者'RandomAccessList',如果这是相关的 - 静态方法确实保留了区别。 – chrylis

+0

我试图使用这个列表进行常规随机访问,所以认为这将是有效的 – amudhan3093

+0

@ amudhan3093使用'List'接口。相信实施。这是最佳做法。 –

2

由于Collections.unmodifiableList()未返回ArrayList,因此返回一个List<T>(接口),它可以是实现List接口的任何后备类,您将得到ClassCastException。从异常情况可以看出,实际上是返回的是UnmodifiableRandomAccessList

当您创建EX_FIELDS应声明它像

List<String> EX_FIELDS = new ArrayList<>(); 

这是可变的,EX_FIELDS是列表和你选择的的ArrayList的实际情况。后来你会做

EX_FIELDS = Collections.unmodifiableList(exList); 

unmodifiableList()返回列表,但你不在乎什么样的它实际上,只要它符合列表接口。

0

其他答案是正确的,但缺少一个关键点:以这种方式创建的不可修改列表仍然可以修改。

这个调用集合类创建一个包装对象,围绕提供exList参数包装。

换句话说:当exList发生变化时,您的包装列表也会发生变化。

所以,当你想要真正确定,你必须先创建一个新的临时列表,你可以添加所有条目exList;然后使用该Collections方法来环绕该临时副本。

+0

所以我应该把它作为EX_FIELDS = Collections来传递。unmodifiableList(new ArrayList (exList));所以现在参考被维护? – amudhan3093

+0

我认为是这样的(但我不是100%确定该ArrayList构造函数是否真的会创建一个副本......所以,如果您想确定,只需查看源代码)。好的问题BTW。 – GhostCat