遇到Java 8 - JDK-8023339:juArrays.asList().removeIf()在抛出java.lang.UnsupportedOperationException时是"懒惰的"

Qui*_*cio 0 java lambda java-8

第一次使用Java 8和我遇到了这个bug.有没有遇到过这个?Bug被标记为已解决但是我不知道为什么我会得到它.我也在bug中找到了列出的示例代码并且确实获得了UOE.这是我的环境:

VM x64中的操作系统

$ cat /etc/lsb-release
DISTRIB_ID="elementary OS"
DISTRIB_RELEASE=0.2.1
DISTRIB_CODENAME=luna
DISTRIB_DESCRIPTION="elementary OS Luna"
Run Code Online (Sandbox Code Playgroud)

JDK

$ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
$ javac -version
javac 1.8.0_25
Run Code Online (Sandbox Code Playgroud)

这是我的考试

package test;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

public class RemoveIfTest {
    static interface I {
        // i want to remove this
        public void a();

        public String b();
    }

    @Test(expected = UnsupportedOperationException.class)
    public void test() {
        List<Method> methods = Arrays.asList(I.class.getMethods());

        // what we have
        methods.forEach(m -> System.out.println(m));
        // output: public abstract void test.RemoveIfTest$I.a()
        //         public abstract java.lang.String test.RemoveIfTest$I.b()

        // old way
        for (Method method : methods) {
            if (method.getReturnType().equals(Void.TYPE)) {
                System.out.println("Remove this > " + method);
            }
        }
        // output: Remove this > public abstract void test.RemoveIfTest$I.a()

        // got UOE
        methods.removeIf(m -> m.getReturnType().equals(Void.TYPE));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是评估线的屏幕截图 在调试

突出显示的行是死亡的地方 在调试

mko*_*bit 6

作为Arrays.asList状态的Javadoc,它是由数组支持的固定大小列表:

返回由指定数组支持的固定大小的列表.(对返回列表的更改"直写"到数组.)此方法与Collection.toArray结合,充当基于数组的API和基于集合的API之间的桥梁.返回的列表是可序列化的并实现RandomAccess.

查看源代码java.util.Arrays,它返回自己的一个List类似于的实现java.util.ArrayList.

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

它不会覆盖remove方法AbstractList,您可以从源中看到它抛出此异常.

public E remove(int index) {
    throw new UnsupportedOperationException();
}
Run Code Online (Sandbox Code Playgroud)

解决方案(如已经说明的那样)是使用支持删除的列表.

List<Method> methods = new ArrayList<>(Arrays.asList(I.class.getMethods()))
Run Code Online (Sandbox Code Playgroud)