【问题标题】:Java "new" keyword in parameter参数中的 Java“new”关键字
【发布时间】:2013-08-16 08:51:07
【问题描述】:

我最近浏览了很多 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));
   }
}

这是来自观察者设计模式的 sn-p。根据我的新理解,name.propertyChange(...) 创建了一个 PropertyChangeEvent 对象,并通过 Java 的观察者模式实现,通过将这个新对象的信息发送给观察者(或类似的东西)自动通知观察者。这是正确的吗?

【问题讨论】:

  • 请注意,在这种特殊情况下(与单个“选定”方法的接口)通常使用“事件”编写的 C# 等效代码 - Handling and Raising Events 而不是与单个成员的接口。
  • 它是一个抽象类,这意味着您可以创建一个新的匿名类来实现它。适合短期任务。
  • 尽量不要在同一个帖子中问多个不相关的问题。而是提出一个新问题。
  • 我已经回答了你的第二个问题。

标签: java oop


【解决方案1】:

这里,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 被声明在更全局的范围内,情况就不是这样了。

关于你的第二个问题:

是的。你是对的,这就是 sn-p 中发生的事情。注意到每次都会创建一个新的PropertyChangeEvent 吗?这样一来,列表中较早出现的侦听器就不会修改列表中较晚出现的项目的PropertyChangeEvent

【讨论】:

    【解决方案2】:

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

    在 Java 中,此语法允许您创建 SelectionAdapter 的匿名子类,覆盖您认为合适的任何方法。这等效于创建一个扩展SelectionAdapter 的命名类,重写任何方法,就像在SelectionAdapter() 构造函数调用之后在花括号中所做的那样,然后在addSelectionListener 的调用中使用该派生类的名称。唯一的区别是这样的派生类有一个名称,而您示例中的匿名类没有可供程序员使用的名称 *

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

    【讨论】:

    • 所以,本质上,这只是一个在运行时按下按钮时创建的临时对象,然后在覆盖的方法完成执行后立即超出范围?
    • @Shaku 不仅对象是临时的,而且类结构也是该调用所独有的。
    • C# 确实有匿名委托。这是最接近等价物的东西。
    • 好的,这一切都清楚了。我在原来的问题中添加了第二部分,你介意也回答一下吗?
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多