代码之家  ›  专栏  ›  技术社区  ›  Henrik Paul

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

  •  41
  • Henrik Paul  · 技术社区  · 17 年前

    确切的上下文和下面的代码应该做什么是非常不相关的-它只是提供某种上下文。

    buttonClick(new Button.ClickEvent(button));
    

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

    buttonClick(button.new ClickEvent(button)); // button instanceof Button
    

    所以,我的问题是: 后一种语法的确切含义是什么?为什么第一个代码段不起作用? Java在抱怨什么,在第二个版本中它在做什么?

    背景资料:两者都有 Button Button.ClickEvent

    6 回复  |  直到 17 年前
        1
  •  71
  •   Jon Skeet    17 年前

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

    该语法创建了一个新的 将其外部类引用设置为 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();
        }
    }
    

    看见 section 8.1.3 of the spec 有关内部类和封闭实例的详细信息。

        2
  •  10
  •   pgras    14 年前

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

    在第二个代码示例中,您有一个Button实例,您创建了一个包含在此Button实例中的ClickEvent实例。。。

        3
  •  9
  •   Daniel Earwicker    17 年前

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

        4
  •  3
  •   starblue    17 年前

    为了避免您自己和其他程序员对这个很少使用的特性感到困惑,您可以始终使内部类保持静态。

        5
  •  2
  •   toto_tico    9 年前

    你真的可以做到 ,但你必须申报 ClickEvent 像 static 在…内 Button ,那么您在使用sintax时应该不会有任何问题:

    buttonClick(new Button.ClickEvent(button));
    

    大体上 静止的 点击事件 直接属于该类 按钮 new Button() 按钮


    // Button.java
    class Button
    {
    
        public static class ClickEvent
        {
            public ClickEvent(Button b)
            {
                System.out.println("Instance: " + this.toString());
            }
        }
    }
    
    // Test.java
    public class Test
    {
        public static void main(String[] args)
        {
            Button button = new Button();
            buttonClick(new Button.ClickEvent(button));
        }
    
        public static void buttonClick (Button.ClickEvent ce) {
        }
    }
    
        6
  •  -1
  •   diginoise    17 年前

    如果您键入,您的代码将被编译

    buttonClick(new Button().ClickEvent(button));
    

    而不是

    buttonClick(new Button.ClickEvent(button));