参数中的Java“new”关键字

时间:2013-08-01 01:44:16

标签: java oop

我最近一直在寻找很多OOP设计模式,而且我遇到了一些我以前从未见过的奇怪事情:

Button button =  new Button(shell, SWT.PUSH);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
    // Handle the selection event
    System.out.println("Called!");
    }
}); 

具体来说,这是做什么的(例如,“new”关键字在这里做什么)?:

    button.addSelectionListener(new SelectionAdapter() {

第二个问题:

private void notifyListeners(Object object, String property, String oldValue, String newValue) {
   for (PropertyChangeListener name : listener) {
      name.propertyChange(new PropertyChangeEvent(this, "firstName", oldValue, newValue));
   }
}

这是观察者设计模式的片段。根据我的新理解,name.propertyChange(...)创建了PropertyChangeEvent的对象,并通过Java的观察者模式实现,通过将这个新对象的信息发送给观察者(或与此非常相似的东西)自动通知观察者。这是对的吗?

3 个答案:

答案 0 :(得分:23)

这里,new关键字正在创建一个匿名类。

当您需要一个侦听器来执行某些操作,并且您希望将代码组合在一起,和/或该类是“一次性”时,这非常有用,这意味着它在其他地方没用。

Here's a link to sun's tutorial匿名课程。所有正常的课程规则都适用。您需要在创建接口时实现抽象方法或所有方法。

范围稍有不同,因为您可以访问您的匿名类嵌套在类中声明的变量。但是,除非将那些局部变量声明为final,否则无法从匿名类访问局部变量。例如:

Button button =  new Button(shell, SWT.PUSH);
final String someString = "hello world!";
button.addSelectionListener(new SelectionAdapter() { 
    @Override
    public void widgetSelected(SelectionEvent e) {
        // Handle the selection event
        System.out.println(someString);
    }
});

如果在更全局的范围内宣布someString,则情况并非如此。

关于你的第二个问题:

是。你是对的,这就是代码片段中发生的事情。请注意,每次都会创建一个新的PropertyChangeEvent?因此,列表中较早出现的侦听器不会修改列表中稍后出现的项目的PropertyChangeEvent

答案 1 :(得分:4)

首先,这是一种特定于Java的语法:C#中没有类似的语法,您必须创建一个扩展object的匿名类,或者创建一个命名类的实例。

在Java中,此语法允许您创建SelectionAdapter的匿名子类,根据您的需要覆盖任何方法。这相当于创建一个扩展SelectionAdapter的命名类,覆盖任何方法,就像在SelectionAdapter()构造函数调用之后的大括号中一样,然后在{的调用中使用该派生类的名称{1}}。唯一的区别是这样的派生类会有一个名称,而你的例子中的匿名类没有名称 * 可供程序员使用。

* 内部匿名类确实有名称:如果查看Java编译器生成的类文件列表,可以看到它们。名称中带有美元符号和数字的文件对应于匿名类。

答案 2 :(得分:0)

new关键字正在创建一个匿名对象。

当您想要创建仅使用一次的实例时,这很有用。

相关问题