为什么Arrays.asList(null)会抛出NullPointerException而Arrays.asList(someNullVariable)不会?

24

这个小程序

public class Client {
    public static void main(String[] args) throws Exception {
        Arrays.asList(null);
    }
}

抛出一个 NullPointerException 异常。

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:221)
    at java.base/java.util.Arrays$ArrayList.<init>(Arrays.java:4322)
    at java.base/java.util.Arrays.asList(Arrays.java:4309)
    at org.example.Client.main(Client.java:10)

然而,这个程序

public static void main(String[] args) throws Exception {
    Arrays.asList(returnNull());
}

private static Object returnNull(){
    return null;
}

他们为什么会表现不同呢?


我认为这可能与方法返回空的“Object”引用有关,而普通的null是不同的?这是一个有趣的问题。 - RobOhRob
6
好的,在第二种情况下,参数被解释为一个大小为1的数组,其中包含一个null值,而在第一种情况下,它被解释为一个null数组。不知道为什么和如何,尽管如此。 - Arnaud
感谢@sotirios-delimanolis的格式化。 - Kousi
相关(甚至是重复的):使用单个null参数调用Java varargs方法? - Lino
1
@Lino 很好发现。我相信这是一个重复的问题。 - Michael
显示剩余2条评论
2个回答

17

区别只在于参数在运行时的使用方式:

asList 的签名为:

public static <T> List<T> asList(T... a)
Arrays.asList(returnNull())将其作为Object调用。这显然不会被解释为数组。Java在运行时创建一个包含一个null元素的数组并将其作为数组传递。这相当于Arrays.asList((Object)null)
但是,当您使用Arrays.asList(null)时,传递的参数被视为数组,并且由于该方法明确拒绝传递空数组(请参见java.util.Arrays.ArrayList.ArrayList(E[])),因此会出现NPE错误。

1

asList()的签名是:- public static <T> List<T> asList(T... a)

因此,args需要类型为T的数组。

第一种情况:当您将null作为参数放入asList中时,该数组将指向null,因此会抛出异常。
第二种情况:当您返回指向null的任何对象的引用时。那么这意味着数组只有一个对象,并且该对象指向null,因此不会抛出异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接