変数は、同じ名前のクラスを隠します。これが、命名規則がある理由の一部です。
パトリシアがコメントで指摘しているように、これは実際には JLS では不明瞭として知られています。
このような状況では、§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()