new Object {}构造

and*_*ins 23 java object

在Java中,创建对象的标准方法是使用

MyClass name = new MyClass();
Run Code Online (Sandbox Code Playgroud)

我也经常看到这个结构

new MyClass() { /*stuff goes in here*/ };
Run Code Online (Sandbox Code Playgroud)

我已经在网上寻找了一段时间,但是找不到第二种构造样式的作用或它是如何做的很好的解释.

有人可以解释你如何以及为什么要使用第二个结构?

Zei*_*ssS 22

这个结构实际上做了两件事:1)它声明了一个匿名类,它扩展了你在构造函数中使用的类,2)创建了这个匿名类的实例.

编辑:使用这样的构造时,您可以通过查看生成的.class文件来观察匿名类.MyClass.class每个匿名子类都有普通文件和另一个文件:MyClass$1.class第一个等等.

  • 从技术上讲,它*声明*一个新类而不是创建一个类.("创建"暗示某些事情在运行时发生......对于类本身而言并非如此.) (2认同)

Nat*_*hes 12

在要创建匿名类的情况下,您将使用第二个构造.如果你有一个将回调作为参数的方法,你可能想要指定回调内联的实现,而不是给它一个名字并将它放在一个单独的文件中或在同一文件的其他地方声明它.

还有一个叫做双括号初始化的技巧,你可以通过使用匿名类来解决没有文字映射和列表的语法,如下所示:

Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};
Run Code Online (Sandbox Code Playgroud)

这里嵌套的大括号创建一个实例初始化器.绑定到map的对象不是HashMap,它的类是一个扩展HashMap的匿名类.(这意味着如果你有关于需要声明串行uid的类的PMD规则,那么它会抱怨这个.)


Car*_*los 7

正如其他人已经说过的,它创建了一个匿名类的实例,子类化Class.以下是一个常用的示例:

panel.addMouseListener(
  new MouseAdapter () {
    @Override
    public void mouseEntered(MouseEvent e) {
      System.out.println(e.toString());
    }
  }
);
Run Code Online (Sandbox Code Playgroud)

上面的代码创建了一个扩展MouseAdapter的匿名类的实例.在匿名类中,该方法mouseEntered已被重写,以证明匿名类基本上与任何其他类一样.这是创建(通常是简单的)侦听器的非常方便和常用的方法.