为什么 inner class 无法访问介于普通方法和静态方法之间的 outer class 方法?

Why inner class can not access outer class method which is overload between normal method and static method?

我有一个这样的测试class。
内部 class 有一个方法 c().
c() 有三行代码。
第一行和第三行没问题,但第二行是错误的 a(java.lang.String) has private access.
为什么方法b()没问题,但是重载的方法a(String s)出错了?

public class Test {

    public void a() {
    }

    private static void a(String s) {
    }

    private static void b() {
    }

    private class Inner extends Test{
        void c() {
            a();
            a("");
            b();
        }
    }
}

重载决策的第一步是确定在哪个 class 中搜索适用的方法 (JLS §15.12.1):

15.12.1. Compile-Time Step 1: Determine Class or Interface to Search

如果你仔细阅读本节,你会看到在这种情况下,

If the form is MethodName, that is, just an Identifier, then:

If the Identifier appears in the scope of a method declaration with that name (§6.3, §6.4.1), then

If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.

对于 a()a("")TInner。对于 b()TTestInner 是包含名称为 a 的方法的最内层类型声明。这是因为 InnerTest 继承了无参数 a(但不是接受字符串的 a,因为它是私有的)。

对于a()Inner中继承的无参数a在后面的重载解析步骤中成功找到。但是,对于 a("")Inner 中没有接受 Stringa!编译器足够聪明,可以在 super class 中寻找私有方法并输出“不可访问”消息。

要调用 Test 中声明的 a,您应该限定它:

Test.this.a(); // or super.a(), note the different objects on which the method is called
Test.a("");

作为实验,您可以尝试让 Inner 不继承 Test,看看会发生什么。现在 Inner 中没有名称为 a 的方法声明,“最里面的此类声明”将是 Test,所有 3 个简单名称调用都可以工作。