3

举个例子。有一个我想使用的对象,称之为Doodad. Doodad元素对浏览器事件的处理效果不佳。a 的典型实例化DoodadDoodad someDoodad = new Doodad();. 显然这不适合我的需要,因为糟糕的事件处理。我是否适合重写该onBrowserEvent()方法,如下所示:

Doodad someDoodad = new Doodad() {
@Override
  public void onBrowserEvent(Event event) {
      switch (DOM.eventGetType(event)) {
          case Event.ONDBLCLICK:
          case Event.ONFOCUS:
          case Event.ONCLICK:
              if (!isEnabled()) {
                  return;
              }
              break;
      }
      super.onBrowserEvent(event);
  }
};

显然这是一个简单的例子,但是我什么时候不想使用匿名内部类呢?它是否曾被明确禁止或不可能?

我看到很多关于第一个问题的答案,但到目前为止没有一个答案回答第二个问题:是否曾明确禁止或不可能使用匿名内部类?

4

7 回答 7

6

通常,匿名内部类的最佳用法是您只想创建此类特定实现的一个实例。当实现非常简单时。理想情况下,它应该包含 1-2 行代码。

onBrowserEvent()在您的情况下,尽管您的方法超过 2 行,但它仍然可以。

于 2011-12-12T14:08:51.027 回答
3

匿名内部类是 Java 创建闭包的语法。这是一个大概的例子:

interface Adder {
  int add(int arg);
}

...

Adder createAdder(int n) {
   final int nf = n;
   return new Adder() { 
       int add(int arg) { return arg + nf; } 
   }
}

方法 createAdder 创建本质上是一个函数,它使用闭包来捕获传递的值 n。闭包在试图使其成为主流的函数式编程中很重要。这就是为什么每个人都在尖叫我们需要 Java 中的“真正的”闭包(即大多数语法比我的示例中更好)。

(当然我不是在回答所提出的问题;我想我所说的是匿名类对我上面描述的有好处。对于几乎所有其他的东西,我都会创建一个命名的内部类,因为如果有任何名称是自记录的并且在我看来更容易阅读)

于 2011-12-12T14:16:29.857 回答
1

通常,事件侦听器是一段不是很通用的代码,但与特定的小部件、按钮、文本字段等相关联。在这种情况下,代码不需要适当地公开以供世界重用。在使用它的地方、就地定义它更容易,这就是匿名内部类的用途。它们允许将代码片段快速嵌入到另一个方法中,而不必担心类名、包、可见性或可重用性。

当然,你可以用匿名内部类做的事情总是可以用适当的独立类来做。但是,当您的事件处理类足够通用(可以处理大量事件)、可重用、有状态或更一般地,当从代码中提取事件管理代码有一些好处时,这样做更有意义定义事件生成元素。

我不确定我是否特别理解你的问题,我希望这条信息能帮助你找到答案。不要犹豫,提出进一步的问题。

于 2011-12-12T14:13:49.947 回答
1

当匿名类实现一种方法和/或半屏时,我会建议它。

如果匿名者有一段不平凡的代码,那么它值得拥有一个命名类恕我直言。

于 2011-12-12T14:27:36.527 回答
0

我的看法:

匿名内部类:来自一个函数的回调(因此您不必编写两次代码)

命名内部类:来自多个函数的回调(或只需要用于父类的内部逻辑的类)

于 2011-12-12T14:10:05.820 回答
0

我只在匿名内部类包含非常少量的代码时才使用它。原因是 IMO 它使代码混乱并使其可读性降低。

如果需要更多代码,我更喜欢创建一个新类,扩展基类(在本例中为 'Doodad()'

于 2011-12-12T14:33:53.990 回答
0

在您的示例中,您希望创建一个单独的类。这是因为您覆盖该方法的原因。也就是说,对浏览器事件的处理很差。

具体来说,您可能希望在几个不同的地方创建这些改进的 Doodad。如果将来更新和改进事件处理会发生什么?您将希望删除所有这些改进的 Doodads 并使用正确的实现。试图找到你所有的匿名小玩意可能会让人厌烦或棘手。而如果你有一个单独的命名类,那么重构这个类将很容易。

此外,如果您为它创建一个单独的类,您改进 Doodad 的原因可以是自我记录。而如果你只有一个匿名类,那么你将不得不写评论或让未来的维护者猜测你为什么做了你所做的事情。

例如。

public class ImprovedBrowserEventHandlingDoodad extends Doodad {
    ...
}

任何类似于闭包的东西通常都适合使用匿名类

例如。

new Thread(new Runnable() {
    @Override
    public void run() {
        doSomething();
    }
}).start();

您只想在这一组特定的情况下做某事,而无需将代码复制并粘贴到其他地方或将其重构为方法。

GUI 的事件处理程序通常使用匿名类,因为它们的使用仅限于 GUI 的设计方式,并且不需要在使用它的特定组件之外创建事件处理程序的单独实例。例如,当您将鼠标悬停在滚动条上时,它的外观通常会发生变化。程序中的任何其他内容都不会导致此更改,通常事件处理程序将是几行告诉滚动条更改其外观的行,例如。scrollbar.setMouseOverEffect(true);.

于 2011-12-12T14:47:34.520 回答