1

我正在准备面试,当我经历空指针异常时,我突然意识到每个对象都能够以某种方式抛出空指针异常,但我似乎无法想象 System、Out 等某些对象会抛出NullPointerException. 谁能提到这样的场景?谢谢!

例如:System.out.println(s.get(name));

4

4 回答 4

8

首先,System不是一个对象。它是一个方法是静态的类。其次,out是该类的静态字段,它(最初)是对标准输出的引用PrintStream。您可以使用 将其更改PrintStream为您自己的System.setOut(PrintStream)

最后,如果你这样做了

System.setOut(null);
System.out.println("42"); // because out is now a null reference 

你会得到一个NullPointerException.

当然,你也可以找到一个System抛出 a的方法NullPointerException

NullPointerException当您尝试取消引用null对象引用时,大多数这些都是由 JVM 抛出的。

你不取消引用一个类。

只有可执行代码可以抛出 NPE,例如方法、构造函数或初始化程序。- 马尔科

于 2013-08-22T15:03:43.423 回答
1

并非每个对象都能够抛出 NullPointerException。通常最好尝试编写不能写的类!

public class ClassThatCannotNPE {

     public int getOne() {
         return 1;
     }
}

您可以对上述类做的唯一两件事是运行其构造函数并调用 getOne()。这些东西都不能NPE。

我们必须小心地定义我们所说的“某事”引发异常的意思。此代码将在第 2 行抛出 NPE:

Date d = null;
System.setProperty("now",d.toString());

但这不是 System 或 System 中的代码抛出异常的示例。上面的代码等价于:

Date d = null;
String temp = d.toString();
System.setProperty(temp);

这也会在第 2 行抛出 NPE——在 System.setProperty() 有机会运行之前。执行顺序与前面的示例完全相同。

关于什么:

System.out.print(null);

这将引发 NPE。但是再一次,抛出它的不是 System 的代码。它相当于:

PrintStream temp = System.out;
temp.print(null);

NPE 发生在第 2 行——它既不是指 System,也不是指任何指 System.


System是一个类,而不是一个对象。它没有构造函数,因此无法实例化。

但是,它有很多静态方法。是否有可能让其中任何一个抛出 NullPointerException?

实际上,通过查看System 的 Javadoc并搜索“NullPointerException” ,我们可以很快找到答案。许多人的第一场比赛是在System.arraycopy()

如果 dest 为 null,则抛出 NullPointerException。

所以你有它:

System.arrayCopy(null,0,null,0,0);

... 会导致 System 类中的一些代码抛出 NPE。


事实上,我们可以查看System 的实际源代码,看看它在哪里抛出 NullPointerExceptions。

488       public static native void arraycopy(Object src,  int  srcPos,
489                                           Object dest, int destPos,
490                                           int length);

哦。arraycopy 是本机的——这意味着实际的实现是 JRE 中的一些 C 代码。但我们还能找到什么?

825       private static void checkKey(String key) {
826           if (key == null) {
827               throw new NullPointerException("key can't be null");
828           }
...

777       public static String setProperty(String key, String value) {
778           checkKey(key);
...

因此,使 System 中的代码抛出 NPE 的另一种方法是:

System.setProperty(null,"value");
于 2013-08-22T15:26:38.200 回答
0

null对象的操作将抛出NullPointerException. 在示例中s.get(name)e if sis nullthen aNullPointerException将被抛出。因为Systemclass,所以静态引用不会为空。查看源代码,您可以看到它out是静态的,final并且最终使用以下命令进行初始化。

setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));

通常,因为它是final这意味着它不会null也不能制造null。但是public static void setOut(PrintStream out)调用一个本机函数private static native void setOut0(PrintStream out),实现 VM 可以在其中创建一个空引用。

这取决于方法的实现是否会抛出NullPointerException. 具体来说println(String),在对传入的变量进行操作之前会进行一次空检查。

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
    }

NullPointerException因此,在这种情况下,只要PrintStream正确初始化方法本身就不应抛出 a在这种情况下System

我希望这有助于回答你的问题。如果没有,请在评论中阐明您在寻找什么。

于 2013-08-22T15:15:24.097 回答
0

Wrapper 类能够抛出 NPE。尽管 java 提供了自动装箱,但与原始数据类型不同,它们默认情况下不会初始化。

Integer r;
if(r>1)
于 2013-08-22T16:02:17.427 回答