new Object {}构造

时间:2010-09-10 21:33:07

标签: java object

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

MyClass name = new MyClass();

我也经常看到构造

new MyClass() { /*stuff goes in here*/ };

我一直在网上寻找一段时间,并且无法找到第二种构造风格的作用或它是如何做的很好的解释。

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

6 个答案:

答案 0 :(得分:21)

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

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

答案 1 :(得分:12)

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

还有一个名为double brace initialization的技巧,您可以通过使用匿名类来解决文字地图和列表的语法问题,如下所示:

Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};

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

答案 2 :(得分:7)

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

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

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

答案 3 :(得分:3)

第二个构造创建一个匿名类的实例,它是Class的子类。

答案 4 :(得分:0)

如果要通过保护构造函数从另一个软件包中新建对象,可以使用:

new Foo() {};

否则,您将获得访问错误。它等于从Foo类继承的匿名子类。

答案 5 :(得分:0)

从jdk8开始,您可能已经看到了不同的语法,就像在使用lambda表达式时创建对象一样。

注意: Lambda表达式不会转换为匿名内部类,它们使用Java 7中引入的invoke dynamic来执行函数方法。

例如:

public class LambdaSample {

    public static void main(String[] args) {
        //If implementation is only one statement then {} braces are optional
        Runnable oneLineImplRunnable = ()->System.out.println("This is one line lambda expression");
        //Multiple statements in the implementation then {} braces are mandatory
        Comparator<StudentTest> stdComparator = (StudentTest s1,StudentTest s2)->{
            if(s1.getFirstName().equals(s2.getFirstName())) {
                return s1.getLastName().compareTo(s2.getLastName());
            }else {
                return s1.getFirstName().compareTo(s2.getFirstName());
            }
        };
    }
}