外部与超级级别

2022-09-04 04:23:29

超级类是否具有比外部类更高的优先级?

假设我们有三个类:

  1. A类
  2. B类
  3. B 类中扩展类 A 的匿名类

A类.java:

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

    public void foo() {
        System.out.println("A foo()");
    }
}

B类.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()");
    }
}

当我调用时,我得到以下输出(这几乎是预期的):new ClassB().test()

A foo()
A Var

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


答案 1

请参阅 6.3.1 重影声明

名为 n 的方法的声明 d 会遮蔽任何其他名为 n 的方法的声明,这些方法位于 d 在整个 d 作用域中出现的点处的封闭作用域中。

这可以解释为“(继承自)的声明掩盖了在发生时,在整个范围内,在封闭范围()中命名的任何其他方法的声明。fooClassAfooClassBfoofoo

同样相关 - 第15.12.1节:

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

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

  • 如果窗体是 MethodName,则有三个子大小写:
    • 如果它是一个简单的名称,即只是一个标识符,则方法的名称是标识符。如果标识符出现在具有该名称的可见方法声明的范围 (§6.3) 内,则必须存在该方法所属的封闭类型声明。设 T 是最里面的此类类型声明。要搜索的类或接口是 T
    • 如果它是 TypeName.Identifier 格式的限定名称,则 [...]
    • 在所有其他情况下,限定名称的格式为 FieldName.Identifier;然后[...]

答案 2

我想你总是会得到."A var"

这是因为您的方法实现是在 的匿名子类上定义的。我认为您不能在方法中访问实例变量,除非您使用 显式引用外部类。test()AB.vartest()ClassB.this.var


推荐