外层与超层

发布于 2024-11-04 18:16:38 字数 907 浏览 1 评论 0原文

super的优先级比outerclass的优先级高吗?

考虑我们有三个类:

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

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

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

A foo()
A Var

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

Does super has higher priority than outer class?

Consider we have three classes:

  1. ClassA
  2. ClassB
  3. Anonymous class in ClassB that extends ClassA

ClassA.java:

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

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

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

When I call new ClassB().test(), I get the following output (which is pretty much expected):

A foo()
A Var

Question: Is it defined somewhere that inner class takes (methods and members) first from the super class and then from the outer class or is it JVM compiler implementation dependent? I have looked over the JLS(§15.12.3) but couldn't find any reference for that, maybe it is pointed out there but I misunderstood some of the terms?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囚我心虐我身 2024-11-11 18:16:38

请参阅6.3.1 隐藏声明

名为 n 的方法的声明 d 隐藏封闭范围内名为 n 的任何其他方法的声明 位于 d 在整个 d 范围内出现的点。

其中可能被解释为“foo的声明(继承自ClassA)隐藏了任何其他名为foo的方法的声明” code> 位于 foo 发生处的封闭范围 (ClassB) 中,贯穿整个 foo 范围。”

同样相关 - 15.12.1 部分:

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

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

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

See 6.3.1 Shadowing Declarations:

A declaration d of a method named n shadows the declarations of any other methods named n that are in an enclosing scope at the point where d occurs throughout the scope of d.

Which may be interpreted as "the declaration of foo (inherited from ClassA) shadows the declaration of any other methods named foo that are in an enclosing scope (ClassB) at the point where foo occurs, throughout the scope of foo."

Also relevant - section 15.12.1:

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

The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to check for definitions of methods of that name. There are several cases to consider, depending on the form that precedes the left parenthesis, as follows:

  • If the form is MethodName, then there are three subcases:
    • If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier. If the Identifier appears within the scope (§6.3) of a visible method declaration with that name, then there must be 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.
    • If it is a qualified name of the form TypeName.Identifier, then [...]
    • In all other cases, the qualified name has the form FieldName.Identifier; then [...]
软糯酥胸 2024-11-11 18:16:38

我认为你总是会得到“A var”

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

I think you are always going to get "A var".

This is because your test() method implementation is being defined on an anonymous subclass of A. I don't think you can access the B.var instance variable within your test() method unless you explicitly refer to the outer class using ClassB.this.var.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文