Reputation: 750
I'm trying to get a unmodifiable ArrayList to a final variable EX_FIELDS. exList is an existing ArrayList object.
EX_FIELDS = (ArrayList<String>) Collections.unmodifiableList(exList);
This code is present in a static block.When the class loads, I get the following error.
java.lang.ClassCastException: java.util.Collections$UnmodifiableRandomAccessList cannot be cast to java.util.ArrayList
I need to use the EX_FIELDS to support random access.Is there any other way to accomplish it?Thanks for any help in advance
Upvotes: 5
Views: 11405
Reputation: 595
The reason error occurs is Collections.unmodifiablelist(exList)
returns a List, what you are trying to do is
ArrayList<T> EX_FIELDS=(ArrayList<T>)List<T>();
List is an interface and cannot be instantiated. The EX_FIELDS variable can only store ArrayList object, hence the classcast exception error.
A proper way to do this is :
List<String> EX_FIELDS=Collections.unmodifiablelist(exList)
Upvotes: 0
Reputation: 140457
The other answers are correct, but missing a crucial point: an unmodifiable list created this way can still be modified.
This call to the Collections class creates awrapper object that wraps around the provided exList argument.
In other words: when exList changes, your wrapped list changes as well.
So when you want to be really sure, you have to first create a new temporary list to which you add all entries of exList; and then you use that Collections method to wrap around that temporary copy.
Upvotes: 0
Reputation: 14800
You get a ClassCastException because Collections.unmodifiableList()
doesn't return an ArrayList, it returns a List<T>
(interface) which can be any backing class that implements the List interface. As you can see from the exception, it is actually returning an UnmodifiableRandomAccessList
.
When you create the variable EX_FIELDS
you should declare it like
List<String> EX_FIELDS = new ArrayList<>();
That is, EX_FIELDS is a List and you have chosen an ArrayList for the actual instance. Later on you'll do
EX_FIELDS = Collections.unmodifiableList(exList);
unmodifiableList()
returns a List, but you don't care what kind it actually is, as long as it conforms to the List interface.
Upvotes: 3
Reputation: 198123
EX_FIELDS
should have type List<String>
, not ArrayList<String>
, and you shouldn't need to do any cast: you should just write
EX_FIELDS = Collections.unmodifiableList(exList);
This is one instance of the much more general rule that you should program to the interface, not the implementation.
Upvotes: 14