Java &引用;变量xxx可能尚未初始化";调用静态方法时,该方法返回相同类型的变量以及该类型本身的相同名称
为什么会出现如下所示的错误?我不确定在JLS中的何处可以找到这样做的限制Java &引用;变量xxx可能尚未初始化";调用静态方法时,该方法返回相同类型的变量以及该类型本身的相同名称,java,jls,Java,Jls,为什么会出现如下所示的错误?我不确定在JLS中的何处可以找到这样做的限制 public class A { static A foo() { return null; } public static void main(String[] args) { A A = A.foo(); } } 编译时出错 A.java:14: error: variable A might not have been initialized
public class A {
static A foo() {
return null;
}
public static void main(String[] args) {
A A = A.foo();
}
}
编译时出错
A.java:14: error: variable A might not have been initialized
A A = A.foo();
^
1 error
该变量隐藏同名的类。这就是为什么会有这样的情况
正如Patricia在评论中指出的,这在JLS中实际上被称为: 在这些情况下,的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包
在您的例子中,会出现编译错误,因为变量隐藏了类型,因为声明是在方法调用之前处理的。这与执行以下操作相同:
public class A {
public void foo() {
String s = s.substring(0, s.length());
}
}
您会遇到同样的错误:
A.java:3: variable s might not have been initialized
String s = s.substring(0, s.length());
^
1 error
你认为输出是什么
$ javac A.java
$ java A
A.foo()
$javac A.java
$java A
A.傅()
请参阅上的JLS,但我在JLS中找不到特定部分,该部分表示它是非法的,并且在类似这样的句子中,变量名隐藏了类型名。此外,如果我没有错,
=
操作符是从右向左求值的,因此编译器可以处理右边(变量不存在的地方),然后处理左边,这是变量声明和赋值,最后一个只是经验解释,编译器不向后读取。声明首先读取,在静态方法的情况下,可能用于推断RHS表达式中的类型,并且始终用于检查类型。它不仅仅是方法调用的副产品。而且,它本身并不是非法的,只是在这种情况下,您最终会得到一个不可编译的表达式。例如,对于2个类A和B,您可能会得到一个可编译程序,它与您认为的不一样。这里的主要线索是错误消息谈到“变量A”,并指向“A.foo()”中的“A”。这意味着编译器认为A是一个变量,而不是一种类型。而且,如果你给你的类和变量起了像A
这样愚蠢的短名字,你就应该得到你得到的一切:-)
$ javac A.java
$ java A
A.foo()