【问题标题】:Why inner class can not access outer class method which is overload between normal method and static method?为什么内部类不能访问在普通方法和静态方法之间重载的外部类方法?
【发布时间】:2021-01-04 09:08:18
【问题描述】:

我有一个这样的测试课。
内部类有一个方法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();
        }
    }
}

【问题讨论】:

  • 我试过jdk1.8,但没有错误
  • 除了错误的行之外,您的代码没有任何问题。您必须以静态方式访问该方法,例如:Test.a("");
  • 静态 a(...) 不是重载。这是个坏主意。要重载它应该是public void a(String s) {...}
  • a(java.lang.String) has private access 虽然 true 与问题无关,也不是问题/问题。

标签: java overloading


【解决方案1】:

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

15.12.1。编译时步骤 1:确定要搜索的类或接口

如果您按照本节进行操作,您将看到在这种情况下,

如果form是MethodName,即只是一个Identifier,那么:

如果标识符出现在具有该名称的方法声明的范围内(第 6.3 节、第 6.4.1 节),则

如果存在该方法是其成员的封闭类型声明,则令 T 为最里面的此类类型声明。要搜索的类或接口是 T。

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

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

要调用Test 中声明的as,您应该对其进行限定:

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

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

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2012-05-27
    • 1970-01-01
    • 2014-07-13
    • 2014-08-31
    • 1970-01-01
    相关资源
    最近更新 更多