Java container — unsupported operation exception

Let’s take an example

importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.Collection;
importjava.util.Collections;
importjava.util.List;

publicclassUnsupportedOperation{
staticvoidtest(Stringmsg,List<String>list){
System.out.println("----------"+msg+"----------");
Collection<String>c=list;
Collection<String>subList=list.subList(1,4);
Collection<String>subList2=newArrayList<>(subList);
try{c.retainAll(subList2);}catch(Exceptione){
System.out.println("retainAll:"+e);
}
try{c.removeAll(subList2);}catch(Exceptione){
System.out.println("removeAll:"+e);
}
try{c.clear();}catch(Exceptione){
System.out.println("clear:"+e);
}
try{c.add("X");}catch(Exceptione){
System.out.println("add:"+e);
}
try{c.addAll(subList2);}catch(Exceptione){
System.out.println("addAll:"+e);
}
try{c.remove("C");}catch(Exceptione){
System.out.println("remove:"+e);
}
try{list.set(0,"W");}catch(Exceptione){
System.err.println("List.set:"+e);
}
System.out.println("List.className="+list.getClass().getSimpleName());
}
publicstaticvoidmain(String[]args){
List<String>list=Arrays.asList("ABCDEFG".split(""));
test("ModifiableCopy",newArrayList<String>(list));
test("Arrays.asList",list);
test("UnmodifiableList",Collections.unmodifiableList(list));
}
}

Implementation results:

----------ModifiableCopy----------
List.className=ArrayList
----------Arrays.asList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=ArrayList
----------UnmodifiableList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.set:java.lang.UnsupportedOperationException
List.className=UnmodifiableRandomAccessList

So why did this happen?It’s easy to understand that the unmodifiable list can’t be modified, but you can see from the results that it’s also ArrayList. Why can’t the list returned by array. Aslist() be modified

Arrays. Aslist() will generate a list, which is based on a fixed size array and only supports those operations that will not change the size of the array. Any method that changes the size of the underlying data structure will produce an unsupported operation exception to indicate the call to the unsupported operation

In fact, in the above code, I deliberately use getsimplename (), because this method will not display the package name. If we will

System.out.println("List.className="+list.getClass().getSimpleName());

Replace with:

System.out.println("List.className="+list.getClass().getName());

So here’s the result:

----------ModifiableCopy----------
List.className=java.util.ArrayList
----------Arrays.asList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=java.util.Arrays$ArrayList
----------UnmodifiableList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=java.util.Collections$UnmodifiableRandomAccessList
List.set:java.lang.UnsupportedOperationException

As you can see, although the name returned by arrays.aslist is called ArrayList, this ArrayList is an internal class in arrays, not java.util.arraylist

Looking at the source code, you can find that the declaration of the internal class of arrays.arraylist is as follows:

privatestaticclassArrayList<E>extendsAbstractList<E>
implementsRandomAccess,java.io.Serializable

In the implementation of this class, there is no method to modify the E [] array (add, delete, clear, etc.)

Therefore, when these methods are called on this kind of object, the implementation of its parent class abstractlist will be called, so the unsupported operation exception is thrown directly

Therefore, it is a common practice for to pass the results of arrays. Aslist() to any collection (or use addall() method or collection. Addall() static method) as the parameters of the construction method, so as to generate a general container that allows all methods to be used — this is shown in the first call to test() in main(), Such a call will produce a new size adjustable underlying data structure the “immutable” method of the collections class wraps the container into an agent. As long as you perform any operation that attempts to modify the container, the agent will generate an unsupported operationexception . The goal of using these methods is to produce “constant” container objects

The last try statement block in test () checks the set () method as part of the list. Arrays. Aslist() returns a fixed size list, while collections. Unmodifiable list() produces a list that cannot be modified. As you can see from the output, it’s OK to modify the elements in the list returned by arrays. Aslist(), because it doesn’t violate the “fixed size” feature. But obviously, the result of unmodifiablelist () is not modifiable in any case

————————————————————–

operations that throw exceptions like the above are called “unsupported operations” in Java containers. So why are methods defined as optional?That’s because it can prevent interface explosion in the design. To make this work:

1. Unsupported operation exception must be a rare event. That is, for most classes, all operations should work, only in special cases. This is true in Java containers, because the container classes you use 99% of the time, such as ArrayList, LinkedList, HashSet, HashMap, and other specific implementations, support all operations

2. If an operation is not supported, it may lead to an unsupported operation exception when the interface is implemented, rather than an exception after the product is delivered to the customer. This is reasonable. After all, it indicates a programming error: an incorrect interface implementation is used

It is worth noting that such operations can only be detected at run time

Similar Posts: