用于实例化内部类的奇怪语法

Hen*_*aul 42 java constructor inner-classes

我没想到在这个阶段我会在Java中遇到全新的语法,但是,我刚刚遇到了一些问题:

确切的上下文以及下面的代码应该做的事情是非常无关紧要的 - 它只是提供某种上下文.

我正在尝试综合在IT Mill Toolkit中创建一个事件,所以我写了这样一行:

buttonClick(new Button.ClickEvent(button));
Run Code Online (Sandbox Code Playgroud)

但是,Eclipse给出了以下错误消息:

不能访问类型为Button的封闭实例.必须使用Button类型的封闭实例限定分配(egxnew A(),其中x是Button的实例).

当我按如下方式重写上面的行时,它不会再抱怨了:

buttonClick(button.new ClickEvent(button)); // button instanceof Button
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:后面的语法是什么意思,确切地说,为什么第一个片段不起作用?什么是Java抱怨,以及它在第二个版本中做了什么?

背景信息:无论ButtonButton.ClickEvent是非抽象公共类.

Jon*_*eet 71

内部类(如Button.ClickEvent)需要引用外部类(Button)的实例.

该语法创建一个新实例,Button.ClickEvent其外部类引用设置为值button.

这是一个例子 - 忽略缺少封装等,它只是为了演示的目的:

class Outer
{
    String name;

    class Inner
    {
        void sayHi()
        {
            System.out.println("Outer name = " + name);
        }
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        outer.name = "Fred";

        Outer.Inner inner = outer.new Inner();
        inner.sayHi();
    }
}
Run Code Online (Sandbox Code Playgroud)

有关内部类和封闭实例的更多信息,请参阅规范的8.1.3节.

  • 如果内部类不需要对外部类的引用来起作用,则可以通过在内部类声明中使用static关键字来消除此要求 - 上面示例中的静态类Inner - 尽管显然您将无法访问Outer.name属性......! (7认同)

pgr*_*ras 10

Button.ClickEvent是一个非静态内部类,因此该类的实例只能包含在Button的实例中.

在第二个代码示例中,您有一个Button实例,并在此Button实例中创建一个ClickEvent实例...


Dan*_*ker 9

Java中的非静态内部类包含一个隐藏引用,该引用指向它声明的外部类的实例.因此,您最初获得的错误消息告诉您,如果不指定内部类的新实例,则无法指定要附加到的外部类的实例.

也许之前没有看到过这种语法的原因是内部类通常在外部类的方法中分配,编译器会自动处理这种情况.