为什么原始数组字段打印出空指针异常?

时间:2013-04-01 23:51:51

标签: java nullpointerexception runtime-error

public class Whatever {
    static double d;
    static char c;
    static String[] s;
    static char[] b;
    static double[] dd;
    static Whatever w;
    static Whatever[] ww;

    public static void main(String[] args) {
        System.out.println(Whatever.d); //prints out 0.0
        System.out.println("hi"+Whatever.c+"hi"); //prints out hi hi
        System.out.println(s); //prints out null
        System.out.println(b); //null pointer exception!
        System.out.println(Whatever.dd);
        System.out.println(Whatever.w);
        System.out.println(Whatever.ww);
    }
}

为什么我会得到空指针异常?

如果可以,请在内存方面进行解释,但是我对记忆有基本的了解,所以也不要太深入。

3 个答案:

答案 0 :(得分:1)

好的,既然你发布了完整的代码,那么它就更容易帮助了!这通常 当您使用原始数组调用PrintStream.println时会发生什么:

String s = String.valueOf(x);

最终会这样做:

return (obj == null) ? "null" : obj.toString();

如您所见,显式处理了提供的对象为null的可能性。但是,对于char数组,PrintStream类,只是存在特定的重载。以下是逻辑的粗略描述:

write(cbuf, 0, cbuf.length);

其中cbuf是给定的char数组。正如您所看到的,它尝试引用字符数组长度,如果数组未初始化,则会耗尽NPE。在实施过程中,这是一个奇怪而不幸的不一致。

所以现在你理解为什么 NPE正在发生 - 修复它只是在尝试打印之前初始化char数组。

答案 1 :(得分:0)

这里有一些问题:

1. You're not allocating any space for `int x`
2. If you want to print the contents of `x`, it should be `x.toString()`
3. What did you expect the output to be from your sample code?

我猜测#3不是你实际使用的,我建议你展示你的真实代码以获得真正的答案:)

希望这可以为你清理一下。

$ cat Whatever.java 
public class Whatever {
    static final int MAX = 5;
    int[] x = new int[MAX]; // allocate array to sizeof '5'

    public Whatever() {
        // do stuff
    }

    public void addStuff() {
        for(int i=0; i<MAX; i++)
            x[i] = i + 2;

    }

    public void printX() {
        for(int i=0; i<MAX; i++)
            System.out.println(i + ": " + x[i]);

    }

    public static void main(String[] args){
        Whatever w = new Whatever();  // new instance of 'Whatever'
        w.addStuff();                 // add some ints to the array
        w.printX();                   // print out the array
        // print the Array 'x'
        System.out.println("Array: " + w.x);
    }
}
$ java Whatever 
0:  2
1:  3
2:  4
3:  5
4:  6
Array: [I@870114c

答案 2 :(得分:0)

问题基本上源于PrintStream.println(...)的实施方式。除char[]外,原始数组被视为java.lang.Object。因此,使用的println重载是println(Object)。在下面,打印对象涉及调用对象的toString()。因此NPE。

如果你想要防御空值,你应该考虑使用String.valueOf(Object)