Tag Archives: ——UnsupportedOperationException

ArrayList reported an error: Unsupported operationexception

Background:

When using the mybatis plus plug-in to interact the springboot project with the MySQL database, the list & lt; object> The type is directly put into the database through the user-defined converter, and the display is successful. However, in the add operation of the list, the unsupported operationexception is returned,

Specific reasons:

The ArrayList in the source code of arrays.aslist in the figure above is not our commonly used ArrayList. Our commonly used ArrayList is java.util.arraylist, while the new in the figure above is java.util.arrays.arraylist, which is an internal class under the arrays class. Its class declaration is as follows:

 

 

It can be seen that both it and java.util.arraylist inherit from the abstractlist abstract class, but it does not implement the add method and remove method. When we call the add method, it actually calls the add method of the parent abstractlist.

 

 

Add calls the add method with two parameters.

 

 

Then you will see throw new unsupported operationexception();

Solution:

To solve the above problem, just put the list into Java. Util. ArrayList, list & lt; Integer> Lists = new ArrayList (list), and then you can use lists to do various operations. Programmers should be careful and look at the source code

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