Java char和int数组差异

Java char和int数组差异,java,Java,当我试图打印未初始化的静态字符数组时,它会给出运行时错误(空指针异常),而未初始化的静态int数组会给出空值。为什么? public class abc { static int arr[]; static char ch[]; public static void main(String[] args) { System.out.println(ch); //it gives null pointer exception at run time

当我试图打印未初始化的静态字符数组时,它会给出运行时错误(空指针异常),而未初始化的静态int数组会给出空值。为什么?

public class abc {
    static int arr[];
    static char ch[];

    public static void main(String[] args) {
        System.out.println(ch); //it gives null pointer exception at run time
        System.out.println(arr); //it gives output as "null".
        }
    }

答案存在于
PrintWriter
源代码中(其中
System.out
就是一个例子)

首先,未初始化的数组作为引用变量,默认值为
null

println(char[])
(最终)尝试对传入的数组调用
.length
。它为null,导致出现
NullPointerException
println(char[])
(最终)调用
write(char[])

匹配的
int[]
没有重载
println
,但有一个
println(对象)
。在那里,它(最终)尝试
String.valueOf
,传递
null
引用,因此
String.valueOf
接受
null
,并返回
字符串
“null”
println(对象)
调用
print(对象)


System.out
PrintStream
的一个实例,这个类有一些重载的
println
方法。就你而言:

  • System.out.println(ch)正在使用
    public void println(char x[])
  • System.out.println(arr)
    正在使用
    公共void println(Object x)
    (没有
    公共void println(int[]x)
    方法,因此
    println
    可以使用的
    int[]
    最接近的可用类型是
    Object
  • 第二种方法是使用

    String.valueOf(x);
    
    要获得要打印的对象的字符串表示形式,方法的
    valueOf
    的代码如下所示

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
    
    因此它是空安全的(如果引用保持空,则返回字符串
    “null”

    第一种方法是在某种程度上使用

    public void write(char cbuf[]) throws IOException {
        write(cbuf, 0, cbuf.length);
                     //    ^^^^^^^ this throws NPE
    }
    

    因为
    cbuf
    null
    cbuf.length
    将抛出NullPointerException,因为
    null
    没有
    length
    (或任何其他)字段。

    这是两种不同的方法,它们的API充分描述了行为

    public void println(对象x)
    首先调用String.valueOf,如果x为null,则返回“null”

    见:

    public void print(char[]c)
    调用print(char[]c)方法,如果c为null,该方法将抛出NullPointerException

    见:


    您实际上在调用两个独立的、重载的
    System.out.println()
    方法<代码>公共void println(char[]x)
    根据文档重载。对于
    int[]
    数组,不存在
    println(Object x)
    的特定重载

    因此,当对整数数组调用
    println()
    时,将调用
    public void println(Object x)
    。根据Javadocs:

    此方法在第一个String.valueOf(x)处调用以获取打印的 对象的字符串值,然后其行为就像调用打印(字符串) 然后是println()

    由于该字符串的值为
    null
    ,因此该方法将打印null

    当使用字符数组作为参数时,
    println()
    方法的工作方式有所不同。从表面上看,该方法本身似乎相似:

    打印一个字符数组,然后终止该行。这种方法 其行为就像调用print(char[]),然后调用println()

    但是,
    print(char[])
    方法在关键方面的行为非常不同:

    打印字符数组。字符被转换成字节 根据平台的默认字符编码 字节的写入方式与write(int)方法完全相同

    因此,它调用不同的方法。
    print(char[])
    的文档明确指出,在您的情况下,会引发异常:

    抛出:NullPointerException-如果[input parameter]s为null

    因此,导致行为差异的原因

    有关
    println
    print
    方法的更多信息,请参见Javadocs:

    非常确定,因为
    println()
    的字符数组版本重载并尝试将数组打印为字符串,而
    int[]
    重载只是将其打印为数组。参考C++的
    std::cout::operatorYep,所有这些都与
    println
    重载有关,而与数组本身无关
    int[]
    char[]
    本质上是相同的,只是
    int
    是4字节的有符号数据,
    char
    是2字节的无符号数据。异常处理非常昂贵。。为什么不检查它是否为空?我知道这对设计师来说是个问题,但我很好奇打印也很贵,我猜?System.out是一个打印流,不是一个打印编写器。那么这不是一个库错误吗?@usr很难说。也许Java作者认为
    print(Object)
    是一种主要用于打印对象状态的方法(借助其
    toString
    方法),所以打印
    null
    感觉不错,但是从
    print(char[])
    中,他们希望打印
    char
    数组和
    char[]中的精确字符
    与字符串相比不是很常见的类型,因为它
    null
    感觉更像是bug而不是预期状态,所以他们决定通过抛出NPE通知程序员它(并停止执行有bug的程序)。但这不一定是真的。您可能需要询问Java设计人员。@usr,虽然如果您想使用
    对象
    重载,那么您可以执行
    System.out.println((Object)chr)
    @oʇoʇǝzuʞ是的,但这会打印数组的
    toString()
    的结果,因此我们会看到类似
    [C@1db9742public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
    
    public void write(char cbuf[]) throws IOException {
        write(cbuf, 0, cbuf.length);
                     //    ^^^^^^^ this throws NPE
    }