System对象可能抛出空指针异常的场景是什么?

时间:2013-08-22 14:57:38

标签: java nullpointerexception

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

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

4 个答案:

答案 0 :(得分:8)

首先,System不是对象。它是一个方法是静态的类。其次,out是该类的静态字段,它(最初)是对标准输出PrintStream的引用。您可以使用PrintStreamSystem.setOut(PrintStream)更改为您自己的System.setOut(null); System.out.println("42"); // because out is now a null reference

最后,如果你做了

NullPointerException

你会得到System

当然,您可以找到NullPointerException的方法,也可以抛出NullPointerException

当您尝试取消引用null对象引用时,JVM会抛出大多数{{1}}。

你不要取消引用一个类。

  

只有可执行代码才能抛出NPE,例如方法,构造函数,   或初始化程序。 - Marko

答案 1 :(得分: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。但是再一次,它不是来自系统的代码抛出它。它相当于:

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

NPE发生在第2行 - 它不是指系统,也不是指任何涉及系统的东西。


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

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

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

  

如果dest为null,则抛出NullPointerException。

所以你有它:

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

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


实际上我们可以查看actual source code for System并查看它抛出NullPointerExceptions的位置。

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

喔。 arraycopy是native - 意味着实际的实现是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");

答案 2 :(得分:0)

null对象的操作将抛出NullPointerException。在示例s.get(name)中,如果snull,则会引发NullPointerException。由于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,而System就是{。}}。

我希望这有助于回答你的问题。如果没有,请在评论中明确说明您的目标。

答案 3 :(得分:0)

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

Integer r;
if(r>1)