Manoj
Manoj

Reputation: 5867

Arrays.asList() doubt?

People say that asList method convert the array into list and its not copying, so every change in 'aList' will reflect into 'a'. So add new values in 'aList' is illegal, since array have fixed size.

But, asList() method returns ArrayList<T>. How the compiler differentiates line 3 from 5. Line 3 gives me exception (UnsupportedOperationException).

        String[] a = {"a","b","c","d"};//1
        List<String> aList =  Arrays.asList(a);//2
        aList.add("e");//3
        List<String> b = new ArrayList<String>();//4
        b.add("a");//5

Upvotes: 16

Views: 17507

Answers (8)

abhihello123
abhihello123

Reputation: 1728

The Return type of Arrays.List is some unknown internal implementation of the List interface and not java.util.ArrayList, so you can assign it only to a List type.

If you assign it to an ArrayList for instance it will give you compile time error "Type mismatch: cannot convert from List to ArrayList"

  ArrayList<String> aList =  Arrays.asList(a);// gives Compile time error

From the Javadoc "Arrays.asList Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) " that means that you are only provided a list view of the Array which IMO is created at runtime and ofcourse you cannot change the size of an array so you can't change size of "Arrays.asList" also.

IMO the internal implementation of Arrays.asList has all the implemented methods which can change the size of the Array as -

void add(E e)
{
//some unknown code
throw(java.lang.UnsupportedOperationException);
}

so whenever you attempt to alter the size of the Array it throws the UnsupportedOperationException.

Still if you want to add some new items to an ArrayList by using such a syntax, you can do so by creating a subclass of Arraylist(preferably by using anonymous subclass of ArrayList). You can pass the return type of Arrays.List to the constructor of ArrayList, (ie. public ArrayList(Collection<? extends E> c)) something like this -

List<String> girlFriends = new java.util.ArrayList<String>(Arrays.asList("Rose", "Leena", "Kim", "Tina"));
girlFriends.add("Sarah");

Now you can easily add Sarah to your GF list using the same syntax.

Upvotes: 6

Lie Ryan
Lie Ryan

Reputation: 64837

Read again, the type of Arrays.asList is:

public static <T> List<T> asList(T... a)

which clearly states that asList returns an object that implements interface java.util.List, nowhere does it says it will return an instance of class java.util.ArrayList.

Next, notice that the documentation on List.add says:

boolean add(E e)

     Appends the specified element to the end of this list (optional operation).

Technically, everytime you use a variable typed as List (instead of ArrayList), you should always be careful to expect that this method may throw UnsupportedOperationException. If you are sure that you will only receive a List implementation that always have the correct semantic of .add(), then you can omit the check at the risk of a bug when your assumption is invalidated.

Upvotes: 10

Qwerky
Qwerky

Reputation: 18435

The key to this is the List implementation returned by

List<String> aList =  Arrays.asList(a);

If you look at the source code in Arrays you will see that it contains an internal private static class ArrayList. This is not the same as java.util.ArrayList.

Upvotes: 1

Andreas Dolk
Andreas Dolk

Reputation: 114767

This List implementation you receive from Arrays.asList is a special view on the array - you can't change it's size.

The return type of Arrays.asList() is java.util.Arrays.ArrayList which is often confused with java.util.ArrayList. Arrays.ArrayList simply shows the array as a list.

Upvotes: 35

Mihai Toader
Mihai Toader

Reputation: 12243

It's an exception and not a compiler error. It is thrown when the program is run and not at the compile time. Basically the actual class that Arrays.asList will return has a throw UnsupporteOperationException inside the add() method.

To be more specific Arrays.asList will return an inner class defined inside the Arrays class that is derived from AbstractList and does not implement the add method. The add method from the AbstractList is actually throwing the exception.

Upvotes: 3

sinelaw
sinelaw

Reputation: 16553

asList returns a fixed-size list, so that you cannot add new elements to it. Because the list it returns is really a "view" of the array it was created from ('a' in your case), it makes sense that you won't be able to add elements - just like you can't add elements to an array. See the docs for asList

Upvotes: 0

OrangeDog
OrangeDog

Reputation: 38777

asList() doesn't return a java.util.ArrayList, it returns a java.util.Arrays$ArrayList. This class doesn't even extend java.util.ArrayList, so its behaviour can be (and is) completely different.

The add() method is inherited from java.util.AbstractList, which by default just throws UnsupportedOperationException.

Upvotes: 5

Joachim Sauer
Joachim Sauer

Reputation: 308021

You're assuming that Arrays.asList() returns an ArrayList, but that's not the case. Arrays.asList() returns an unspecified List implementation. That implementaton simply throws an UnsupportedOperationException on each unsupported method.

Upvotes: 3

Related Questions