public static void main(String[] args) {
String s1 = null;
String s2;
s1.trim(); //No compile error. But run time error
s2.trim(); //compile error.
}
在上面的代码中,初始化后没有s1
的赋值
编译器知道s1
是null
。那么为什么不显示像s1.trim()
这样的s2
的编译错误?
答案 0 :(得分:4)
由于s2
未初始化且s1
已初始化为null
对于Que 1:您实际上正在trim()
执行null
操作,因此它会抛出NPE(NullPointerException
)。
对于Que 2: 有关详细说明,请参阅JLS的§4.12.5:
在使用局部变量之前,必须明确给出一个值, 通过初始化或分配,以可以验证的方式 由编译器使用明确赋值的规则。
答案 1 :(得分:2)
String s2;
这是一个局部变量。在使用本地变量之前,必须提供一个默认值,否则编译器会投诉。你无法编译代码的原因。
String s1 = null;
您正在初始化此局部变量。所以没有编译问题,但你不能对null的东西执行修剪操作。所以你得到的NPE是一个运行时异常,默认情况下不能缓存(尽管你可以)。
答案 2 :(得分:0)
由于初始化了s1,编译器很高兴,尽管可能会对可能的NullPointerException发出警告
答案 3 :(得分:0)
1) 空指针异常..因为没有对象但是在null上操作; 2) 无需初始化即可使用局部变量
答案 4 :(得分:0)
必须显式初始化局部变量才能使用。设置s1=null
是一个初始化,虽然相对无用。由于s2
位于堆栈上且未初始化为cannot be used。
s1
获得运行时异常,但s2
出现编译时错误。
答案 5 :(得分:0)
在创建字符串对象时,我们应该初始化一些值。
String s1 = null;
它保持空值。
String s2;
但是变量s2为空值但未分配。
答案 6 :(得分:0)
这是因为java编译器在编译代码时会查找赋值运算符(=)。当编译器在s1的情况下触发“=”符号时,它认为s1初始化而不管初始化值如何。在s2的情况下,编译器找不到赋值运算符,因此在词法阶段它在错误表中创建一个条目,指出“变量s2可能尚未初始化”
答案 7 :(得分:0)
Java编译器将检查本地变量是否已初始化。如果没有,编译器会抛出错误。这是必需的,因为与实例变量不同,java不会使用其默认值初始化局部变量。 一旦变量初始化,即使它被初始化为null,编译器也不会抱怨,因为编译器认为变量将在程序过程中的某处以非空值重新初始化。编译器,无法检查在程序过程中重新初始化的值,因为在运行时期间值可以是任何值。但是如果值仍然为null,则会调用实例方法,JVM会抛出NullPointerException,因为它仅在运行时才知道。 说得通?
答案 8 :(得分:0)
让我们以JLS的明确分配为例:
{
int k;
int n = 5;
if (n > 2)
k = 3;
System.out.println(k); /* k is not "definitely assigned"
before this statement */
}
有人可能会说编译器知道执行肯定会到达if
块内,从而导致k
的分配,所以它应该编译得很好,但事实并非如此。
我认为这是java作者决定他们希望编译器有多聪明,同时考虑编译时间和/或其他因素的可接受值。