Java 为什么类型为空的变量声明显示编译错误,而不是null声明?

Java 为什么类型为空的变量声明显示编译错误,而不是null声明?,java,string,compiler-errors,variable-assignment,Java,String,Compiler Errors,Variable Assignment,在上述代码中,初始化后,s1没有赋值 编译器知道s1为null。那么为什么不显示s1.trim()的编译错误,比如s2?,因为s2未初始化,而s1已初始化为null 对于Que 1:您实际上正在对null执行trim()操作,因此它将按原样抛出NPE(NullPointerException) 对于Que 2: 有关非常详细的说明,请参见JLS中的: 局部变量在使用前必须显式给定一个值, 通过初始化或赋值,以可验证的方式 由编译器使用规则进行确定赋值 这是一个局部变量。局部变量并没有给定默认值。

在上述代码中,初始化后,
s1
没有赋值
编译器知道
s1
null
。那么为什么不显示
s1.trim()
的编译错误,比如
s2

,因为
s2
未初始化,而
s1
已初始化为
null

对于Que 1:您实际上正在对
null
执行
trim()
操作,因此它将按原样抛出NPE(
NullPointerException

对于Que 2: 有关非常详细的说明,请参见JLS中的:

局部变量在使用前必须显式给定一个值, 通过初始化或赋值,以可验证的方式 由编译器使用规则进行确定赋值

这是一个局部变量。局部变量并没有给定默认值。在使用它之前,您必须提供一个默认值,否则编译器会抱怨。无法编译代码的原因

String s2;

您正在初始化此局部变量。因此,没有编译问题,但不能对空值执行修剪操作。因此,您得到的是NPE,这是一个运行时异常,默认情况下不能缓存(尽管您可以缓存)。

由于s1已初始化,编译器很高兴,尽管它可能会对可能出现的NullPointerException发出警告 空指针异常。。因为没有对象,只能在null上操作; 2)
没有初始化就不能使用局部变量

必须显式初始化局部变量才能使用。设置
s1=null
是一种初始化,尽管这是一种相对无用的初始化。因为
s2
在堆栈上并且未初始化它


s1
获取运行时异常,但
s2
获取编译时错误。

在创建字符串对象时,我们应该初始化一些值

String s1 = null;
它持有空值

   String s1 = null;

但变量s2为空值,但未赋值。

这是因为java编译器在编译代码时查找赋值运算符(=)。当编译器在s1的情况下触发“=”符号时,不管初始化值如何,它都认为s1已初始化。对于s2,编译器找不到赋值运算符,因此在词法阶段,它会在错误表中创建一个条目,说明“变量s2可能尚未初始化”

Java编译器将检查局部变量是否已初始化。否则,编译器将抛出一个错误。这是必需的,因为与实例变量不同,java不会使用其默认值初始化局部变量。 一旦变量被初始化,即使它是用null初始化的,编译器也不会抱怨,因为编译器假定,在程序运行过程中,变量将在某个地方用非null值重新初始化。编译器,无法检查在程序过程中重新初始化的值,因为该值在运行时可以是任何值。但是,如果该值仍然为null,则调用实例方法时,JVM将抛出NullPointerException,因为只有在运行时才知道它。
有道理吗

让我们以JLS的明确分配为例:

   String s2;
有人可能会说,编译器知道执行肯定会到达
if
块内部,从而导致
k
的赋值,因此它应该可以很好地编译,但事实并非如此


我认为这是java作者做出的决定,他们希望编译器有多聪明,同时要记住编译时间的可接受值和/或其他因素。

可能是离题的,但如果使用eclipse,您将收到以下警告:this@Keyser是,请参阅我的答案。@Keyser如果它是一个实例变量,则会自动指定默认值(字符串为null)在这种情况下,您将不会遇到编译问题,而是NPE。
   String s2;
{
    int k;
    int n = 5;
    if (n > 2)
        k = 3;
    System.out.println(k);  /* k is not "definitely assigned"
                               before this statement */
}