为什么 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("")
,T
是 Inner
。对于 b()
,T
是 Test
。 Inner
是包含名称为 a
的方法的最内层类型声明。这是因为 Inner
从 Test
继承了无参数 a
(但不是接受字符串的 a
,因为它是私有的)。
对于a()
,Inner
中继承的无参数a
在后面的重载解析步骤中成功找到。但是,对于 a("")
,Inner
中没有接受 String
的 a
!编译器足够聪明,可以在 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 个简单名称调用都可以工作。
我有一个这样的测试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("")
,T
是 Inner
。对于 b()
,T
是 Test
。 Inner
是包含名称为 a
的方法的最内层类型声明。这是因为 Inner
从 Test
继承了无参数 a
(但不是接受字符串的 a
,因为它是私有的)。
对于a()
,Inner
中继承的无参数a
在后面的重载解析步骤中成功找到。但是,对于 a("")
,Inner
中没有接受 String
的 a
!编译器足够聪明,可以在 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 个简单名称调用都可以工作。