【问题标题】:What does implicit "this" refer to in an anonymous class?隐含的“this”在匿名类中指的是什么?
【发布时间】:2016-06-29 20:18:16
【问题描述】:

在下面的代码中,我注意到我可以在不引用 HelloWorld 对象的情况下调用 getWorld()?但是隐含的“this”关键字现在不是指的是内部匿名类吗?如果是这样,为什么我可以调用 getWorld()?

public class HelloWorld {
    public void getWorld() {
        this.setListener(new MyListenerInterface(){
            @Override
            public void innerMethod() {
                getWorld();
            }
        });
    }
}

忽略代码中的递归。

【问题讨论】:

    标签: java this anonymous-inner-class


    【解决方案1】:

    答案在Section 15.12 of the JLS

    如果是简单的名字,即只是一个Identifier,那么方法的名字就是Identifier。

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

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

    通过仅使用方法的简单名称,调用哪个方法的解析会查找封闭的方法,直到找到具有该名称的方法,然后尝试使用该方法(或多个方法)找到一个完全匹配的。

    这与使用this.getWorld() 的情况不同,因为this 明确地指向内部类实例。这会导致不同类型的解析(规范的Typename . Identifier 部分,就在链接的引用下方),它不查看封闭的外部类。

    这样做的一个有趣结果是,您可以通过向具有相同名称但不同数量的内部类添加一个方法来导致代码停止编译。由于它在尝试确定要解析它的类实例时只搜索名称本身,因此它将尝试使用内部类,但找不到精确匹配的方法。

    所以这个:

    public class HelloWorld {
        public void getWorld() {
            this.setListener(new MyListenerInterface(){
                @Override
                public void innerMethod() {
                    getWorld();
                }
                void getWorld(int i){}
            });
        }
    }
    

    无法编译。方法名称解析将在内部类中发现getWorld,因此将停止向上搜索层次结构。但是当它尝试进行arity解析时,它会发现类中的(一个)getWorld方法都不匹配,并且会失败。

    TL;DR - 仅使用简单名称与使用this.method() 完全相同,尽管它通常评估为相同的东西。语言规范有处理这种情况的特定规则,它可以允许它查看任何封闭的实例以找到匹配的方法。

    【讨论】:

      【解决方案2】:

      调用getWorld 你会离开匿名类并回到顶级类,所以this 指的是创建匿名类的对象。

      就像调用其他类的方法一样,this 指向不同的对象(不是调用者,而是被调用者)。

      【讨论】:

      • 我认为他是在询问 Java 语言本身的工作原理。你是对的,这就是它正在做的事情,但为什么呢?
      猜你喜欢
      • 1970-01-01
      • 2017-10-14
      • 2020-10-29
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多