匿名内部类在Java中是如何使用的?

匿名类在Java中的用途是什么?我们可以说使用匿名类是Java的优势之一吗?


答案 1

通过“匿名类”,我认为你的意思是匿名的内部类

当使用某些“附加项”(如重写方法)创建对象的实例时,匿名内部类可能很有用,而不必实际对类进行子类类化。

我倾向于将其用作附加事件侦听器的快捷方式:

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // do something
    }
});

使用这种方法可以使编码更快一些,因为我不需要创建一个实现的额外类 - 我可以实例化一个匿名的内部类,而无需实际创建单独的类。ActionListener

我只将这种技术用于“快速而肮脏”的任务,在这些任务中,使整个类感觉没有必要。具有多个执行完全相同操作的匿名内部类应重构为实际类,无论是内部类还是单独的类。


答案 2

匿名内部类实际上是闭包,因此它们可用于模拟 lambda 表达式或“委托”。例如,采用以下接口:

public interface F<A, B> {
   B f(A a);
}

您可以匿名使用它在 Java 中创建一等函数。假设您有以下方法,该方法返回给定列表中大于 i 的第一个数字,如果没有数字较大,则返回 i:

public static int larger(final List<Integer> ns, final int i) {
  for (Integer n : ns)
     if (n > i)
        return n;
  return i;
}

然后你有另一个方法,返回给定列表中第一个小于i的数字,或者如果没有数字更小,则返回i:

public static int smaller(final List<Integer> ns, final int i) {
   for (Integer n : ns)
      if (n < i)
         return n;
   return i;
}

这些方法几乎完全相同。使用一等函数类型 F,我们可以将它们重写为一个方法,如下所示:

public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
   for (T t : ts)
      if (f.f(t))
         return t;
   return z;
}

您可以使用匿名类来使用 firstMatch 方法:

F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
   Boolean f(final Integer n) {
      return n > 10;
   }
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);

这是一个非常人为的例子,但很容易看出,能够像传递值一样传递函数是一个非常有用的功能。参见Joel本人的“Can Your Programming Language Do This”。

一个很好的库,用于以这种风格编程Java:函数式Java。


推荐