Javaトラップ(一)——ArrayList.asList

5524 ワード

一、問題コード
    あまり話さないで、直接問題コードに行きます.
package com.pajk.recsys.dk.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.pajk.recsys.utils.CommonUtils;

public class CommonTest {
    public static List UnsupportedOperationExceptionTest(List source){
        source.add("12312");
        return source;
    }

    public static void main(String args[]){
        String str = "123,456,7899";

        String[] items = str.trim().split(",");
        List realAdd = Arrays.asList(items);
        realAdd.add("123123123");
        List xxx = UnsupportedOperationExceptionTest(realAdd);
        System.out.println(xxx);
    }

}

上記のコードは例外を放出します.
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)
    at com.pajk.recsys.dk.test.CommonTest.main(CommonTest.java:20)

問題はArrays.asList(items)です.
二、Arrays.asList()ソースコード
private static final class ArrayList<E> extends AbstractList<E>
     implements Serializable, RandomAccess
   {
     // We override the necessary methods, plus others which will be much
     // more efficient with direct iteration rather than relying on iterator().

     /**
      * Compatible with JDK 1.4.
      */
     private static final long serialVersionUID = -2764017481108945198L;

     /**
      * The array we are viewing.
      * @serial the array
      */
     private final E[] a;

     /**
      * Construct a list view of the array.
      * @param a the array to view
      * @throws NullPointerException if a is null
      */
     ArrayList(E[] a)
     {
       // We have to explicitly check.
       if (a == null)
         throw new NullPointerException();
       this.a = a;
     }
....
 public static  List asList(final T... a)
   {
     return new Arrays.ArrayList(a);
  }

上のコードから分かるように、asListはfinalの固定長のArrayListクラスを返し、java.util.ArrayListではないので、add、removeなどlist長を変更する操作を直接利用することはできません.
三、修正方法List realAdd = new ArrayList(Arrays.asList(items));