方法调用:Collections.emptyList()在不同情况下显示不同的行为?

S K*_*mar 1 java collections exception list

根据Collections.emptyList()方法的注释,它返回一个空的不可变列表.

如果我们直接赋值给对象,这是合理的.例:

public class ImmutableList {
    public static void main(String[] args){
        List<String> namesList=Collections.emptyList();
        String[] names = {"Name1", "Name2", "Name3"};
        namesList.addAll(Arrays.asList(names));     
    }

    private List<String> getList() {
        String[] names = {"Name1", "Name2", "Name3"};
        return Arrays.asList(names);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们运行上面的程序,它会引发异常

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
    at org.learn.list.ImmutableList.main(ImmutableList.java:11)
Run Code Online (Sandbox Code Playgroud)

但是,如果我们将方法的输出分配给此变量,那么它运行正常.例:

public class ImmutableListTest2 {
    public static void main(String[] args){
        List<String> namesList=Collections.emptyList();
        ImmutableListTest2 ce = new ImmutableListTest2();       
        namesList = ce.getList(); 
        namesList.forEach(System.out::print);
    }

    private List<String> getList() {
        String[] names = {"Name1", "Name2", "Name3"};
        return Arrays.asList(names);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出继电器:

Name1Name2Name3
Run Code Online (Sandbox Code Playgroud)

我的问题是namesList在任何情况下都应该是不可变的.为什么我们能够在第二种情况下改变这个变量.

它应该抛弃UnsupportedOperationException所有情况.任何帮助表示赞赏.谢谢!

Era*_*ran 6

namesList不是一成不变的.List<String>它引用的原始(返回Collections.emptyList())是不可变的.

namesList是一个List<String>类型的变量.因此,您可以为其分配对任何List<String>实例的引用,可变或不可变.当您为其分配List返回的时ce.getList(),它不再引用不可变的List.

如果要防止这种情况,请将其设为final变量,以防止重新分配:

final List<String> namesList=Collections.emptyList();
Run Code Online (Sandbox Code Playgroud)