外部与超级课程

MBy*_*ByD 14 java inheritance inner-classes

超级优先级比外级优先级高吗?

考虑我们有三个类:

  1. ClassA的
  2. ClassB的
  3. ClassB中的匿名类,它扩展了ClassA

ClassA.java:

public class ClassA {
    protected String var = "A Var";

    public void foo() {
        System.out.println("A foo()");
    }
}
Run Code Online (Sandbox Code Playgroud)

ClassB.java:

public class ClassB {
    private String var = "B Var";

    public void test() {

        new ClassA() {
            public void test() {
                foo();
                System.out.println(var);
            }
        }.test();
    }

    public void foo() {
        System.out.println("B foo()");
    }
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时new ClassB().test(),我得到以下输出(这是非常期待的):

A foo()
A Var
Run Code Online (Sandbox Code Playgroud)

问题:它是在某个地方定义的,内部类首先从超类中获取(方法和成员),然后从外部类中获取,还是依赖于JVM编译器实现?我查看了JLS(§15.12.3),但找不到任何参考,也许有人指出,但我误解了一些条款?

aio*_*obe 5

请参见6.3.1影子声明:

的声明d命名方法的Ñ 阴影命名的任何其它方法的声明Ñ是在封闭的范围在其中点d发生在整个范围d.

可以被解释为"的声明foo(从继承ClassA)阴影的命名的任何其它方法的声明foo是在一个封闭的范围(ClassB)在其中点foo发生时,整个的范围foo".

也相关 - 第15.12.1节:

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

在编译时处理方法调用的第一步是确定要调用的方法的名称以及检查该名称的方法定义的类或接口.有几种情况需要考虑,具体取决于左括号前面的形式,如下所示:

  • 如果表单是MethodName,则有三个子句:
    • 如果它是一个简单的名称,即只是一个标识符,那么该方法的名称就是标识符.如果标识符出现在具有该名称的可见方法声明的范围(第6.3节)中,则必须存在该方法所属的封闭类型声明.设T是最里面的类型声明.类或接口,以搜索为T.
    • 如果它是TypeName.Identifier形式的限定名称,那么[...]
    • 在所有其他情况下,限定名称的格式为FieldName.Identifier; 然后 [...]

  • 不好了.我喜欢浏览JLS ..我每次都学到新东西:-) (3认同)