调用静态方法时"变量xxx可能尚未初始化",该方法返回相同类型的变量和类型本身的相同名称

Jai*_*zel 3 java jls

为什么它会因下面显示的错误而失败?我不确定JLS在哪里寻找限制做这样的事情.

public class A {

    static A foo() {
        return null;
    }

    public static void main(String[] args) {
        A A = A.foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时出错

A.java:14: error: variable A might not have been initialized
        A A = A.foo();
              ^
1 error
Run Code Online (Sandbox Code Playgroud)

Fra*_*eau 7

变量隐藏了同名的类.这就是为什么有命名约定的部分原因.


正如帕特里夏在评论中指出的那样,这在JLS中实际上被称为模糊:

在这些情况下,§6.5的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包.


在您的情况下,您会收到编译错误,因为变量隐藏了类型,因为在方法调用之前处理了声明.这与执行以下操作相同:

public class A {
    public void foo() {
        String s = s.substring(0, s.length());
    }
}
Run Code Online (Sandbox Code Playgroud)

你得到同样的错误:

A.java:3: variable s might not have been initialized
        String s = s.substring(0, s.length());
                   ^
1 error

在评论中,你说你找不到JLS说你的建筑是非法的.它本身并不违法,因为模糊的结果是.考虑两个类的情况,你也可以因为模糊而得到不需要的电话,这不是非法的,只是令人困惑:

public class A {
    public void foo() {
        System.out.println("A.foo()");
    }

    public static void main(String[] args) {
        A B = new A();
        B.foo();
    }

    public static class B {
        public static void foo() {
            System.out.println("B.foo()");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您认为输出是什么?

$ javac A.java
$ java A
A.foo()

  • 参见["Obscuring"]上的JLS(http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.4.2) (4认同)