A static method that can create a List object from variadic arguments, ʻArrays.asList (T ... t)
, but does not return an object of
`java.util.ArrayList`` because they have similar names. ..
Code like the following will result in a compilation error.
java.util.ArrayList<Integer> arrayList = Arrays.asList(1,2,3); // no instance(s) of type variable(s) T exist so that List<T> conforms to ArrayList<Integer>
Since it is returned as a List type, it looks good if you cast it to java.util.ArrayList
, and the compile error actually disappears.
* A bad cast
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);
But at runtime I get a ClassCastException
. Never do it.
Take a peek at the implementation to see what the `ʻArrays.asList`` method is returning.
Array.java
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
...Abbreviation
You are returning an ArrayList with return new ArrayList <> (a);
! I want to say that, but let's follow the `ʻArrayList`` further.
Array.java
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
...Abbreviation
You can see that it has a nested private and static ArrayList class
in the Array class, and it is new and instantiated.
And that ArrayList class inherits from ʻAbstractList``, not the
`java.util.ArayList`` class. (Since java.util.ArayList also inherits AbstractList, the inheritance hierarchy is the same)
__ In other words, you can see that Arrays.asList returns an instance of the same name as java.util.ArrayList (excluding packages) but a different class (no inheritance relationship). __
__ The java.util.ArrayList class
and the ArrayList class`` in the `ʻArrays class are not compatible. __
Therefore the above
* A bad cast
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);
Found out why it throws a ClassCastException
.
If you read [Official documentation of Arrays class] link-Arrays, the explanation of asList is
Returns a fixed size list that works with the specified array.
a.
In other words, the __ArrayList class in the Arrays class is a fixed-length list , which is different from the __ variable-length list java.util.ArrayList
.
As confirmed above, the ArrayList class in Arrays has a fixed length, so the number of elements in the __list cannot be changed. __
So the following code will compile, but the exception `ʻUnsupportedOperationException`` will occur at runtime.
//I'm trying to add an element to a fixed length list
List<Integer> list1 = Arrays.asList(1,2,3);
list1.add(4); // UnsupportedOperationException
This is in the description of the add method of the inherited [Official documentation of the AbstractList class] link-AbstractList.
This implementation throws an UnsupportedOperationException unless add (int, E) is overridden.
This is because the ArrayList class in Arrays does not override the ʻadd (int, E) method
.
Many people would use add if they didn't know that Arrays.asList would return a fixed-length list.
By the way, if you also use the remove method, `ʻUnsupportedOperationException`` will occur at runtime.
It's a fixed-length list, so I feel a strong will to never change the size.
The list returned by `ʻArrays.asListis not compatible with
java.util.ArrayList``. Don't cast.
Incidentally, the list returned by `ʻArrays.asList`` is a fixed-length list. If you change the size later, an exception will occur.
If you really want to use it with java.util.ArrayList
type, pass it to the argument of the constructor and use it. Since it is no longer a fixed length, you can add and remove it.
//No compile error or ClassCastException at run time
List<Integer> list1 = Arrays.asList(1,2,3);
ArrayList<Integer> list2 = new ArrayList<>(list1);
However, since __Arrays.asList returns completely eliminates the merit of fixed-length list __, I think that it is not necessary to write such code, and it is better to handle the list with the List interface type. I think it's the best.