3

为什么它会失败并出现如下所示的错误?我不确定在 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
        A A = A.foo();
              ^
1 error
4

1 回答 1

7

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


正如 Patricia 在评论中指出的那样,这实际上在 JLS 中被称为obscuring

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


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

public class A {
    public void foo() {
        String s = s.substring(0, s.length());
    }
}

你会得到同样的错误:

A.java:3:变量 s 可能尚未初始化
        字符串 s = s.substring(0, s.length());
                   ^
1 个错误

在评论中,你说你没有找到 JLS 说你的建筑是非法的。它本身并不违法,由于模糊不清的结果是。考虑有 2 个类的情况,由于模糊,您也可能会收到不需要的呼叫,这不是非法的,只是令人困惑:

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()");
        }
    }
}

你认为输出是什么?

$ javac A.java
$java A
A.foo()
于 2012-12-19T20:59:56.290 回答