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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/355167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:45:33  来源:igfitidea点击:

How are Anonymous inner classes used in Java?

javaanonymous-classanonymous-inner-class

提问by Warrior

What is the use of anonymous classes in Java? Can we say that usage of anonymous class is one of the advantages of Java?

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

采纳答案by coobird

By an "anonymous class", I take it you mean anonymous inner class.

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

An anonymous inner class can come useful when making an instance of an object with certain "extras" such as overriding methods, without having to actually subclass a class.

匿名内部类在创建具有某些“额外”(例如覆盖方法)的对象实例时非常有用,而无需实际对类进行子类化。

I tend to use it as a shortcut for attaching an event listener:

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

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

Using this method makes coding a little bit quicker, as I don't need to make an extra class that implements ActionListener-- I can just instantiate an anonymous inner class without actually making a separate class.

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

I only use this technique for "quick and dirty" tasks where making an entire class feels unnecessary. Having multiple anonymous inner classes that do exactly the same thing should be refactored to an actual class, be it an inner class or a separate class.

我只将这种技术用于“快速而肮脏”的任务,在这种情况下,让整个班级感觉没有必要。拥有多个做完全相同事情的匿名内部类应该重构为一个实际的类,无论是内部类还是单独的类。

回答by Uri

You use it in situations where you need to create a class for a specific purpose inside another function, e.g., as a listener, as a runnable (to spawn a thread), etc.

您可以在需要在另一个函数内为特定目的创建类的情况下使用它,例如,作为侦听器、作为可运行对象(生成线程)等。

The idea is that you call them from inside the code of a function so you never refer to them elsewhere, so you don't need to name them. The compiler just enumerates them.

这个想法是你从函数的代码内部调用它们,所以你永远不会在其他地方引用它们,所以你不需要命名它们。编译器只是枚举它们。

They are essentially syntactic sugar, and should generally be moved elsewhere as they grow bigger.

它们本质上是语法糖,随着它们变大,通常应该移到其他地方。

I'm not sure if it is one of the advantages of Java, though if you do use them (and we all frequently use them, unfortunately), then you could argue that they are one.

我不确定这是否是 Java 的优势之一,但如果您确实使用它们(不幸的是,我们都经常使用它们),那么您可能会争辩说它们是其中之一。

回答by madlep

They're commonly used as a verbose form of callback.

它们通常用作回调的详细形式。

I suppose you could say they're an advantage compared to not having them, and having to create a named class every time, but similar concepts are implemented much better in other languages (as closures or blocks)

我想你可以说它们与没有它们相比是一个优势,并且每次都必须创建一个命名类,但是类似的概念在其他语言中实现得更好(作为闭包或块)

Here's a swing example

这是一个挥杆示例

myButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        // do stuff here...
    }
});

Although it's still messily verbose, it's a lot better than forcing you to define a named class for every throw away listener like this (although depending on the situation and reuse, that may still be the better approach)

虽然它仍然很冗长,但比强迫你为每个丢弃的监听器定义一个命名类要好得多(尽管取决于情况和重用,这可能仍然是更好的方法)

回答by Lars A Fr?yland

Yes, anonymous inner classes is definitely one of the advantages of Java.

是的,匿名内部类绝对是 Java 的优势之一。

With an anonymous inner class you have access to final and member variables of the surrounding class, and that comes in handy in listeners etc.

使用匿名内部类,您可以访问周围类的最终变量和成员变量,这在侦听器等中派上用场。

But a major advantage is that the inner class code, which is (at least should be) tightly coupled to the surrounding class/method/block, has a specific context (the surrounding class, method, and block).

但是一个主要的优点是内部类代码(至少应该)与周围的类/方法/块紧密耦合,具有特定的上下文(周围的类、方法和块)。

回答by Apocalisp

Anonymous inner classes are effectively closures, so they can be used to emulate lambda expressions or "delegates". For example, take this interface:

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

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

You can use this anonymously to create a first-class functionin Java. Let's say you have the following method that returns the first number larger than i in the given list, or i if no number is larger:

您可以匿名使用它在 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;
}

And then you have another method that returns the first number smaller than i in the given list, or i if no number is smaller:

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

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

These methods are almost identical. Using the first-class function type F, we can rewrite these into one method as follows:

这些方法几乎相同。使用一等函数类型 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;
}

You can use an anonymous class to use the firstMatch method:

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

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

This is a really contrived example, but its easy to see that being able to pass functions around as if they were values is a pretty useful feature. See "Can Your Programming Language Do This"by Joel himself.

这是一个非常人为的例子,但很容易看出,能够将函数当作值来传递是一个非常有用的特性。请参阅乔尔本人的“你的编程语言能做到这一点吗”

A nice library for programming Java in this style: Functional Java.

以这种风格编写 Java 的一个不错的库:Functional Java。

回答by Chase Seibert

I use them sometimes as a syntax hack for Map instantiation:

我有时将它们用作 Map 实例化的语法技巧:

Map map = new HashMap() {{
   put("key", "value");
}};

vs

对比

Map map = new HashMap();
map.put("key", "value");

It saves some redundancy when doing a lot of put statements. However, I have also run into problems doing this when the outer class needs to be serialized via remoting.

它在执行大量 put 语句时节省了一些冗余。但是,当外部类需要通过远程处理进行序列化时,我也遇到了问题。

回答by Kumar Vivek Mitra

GuideLines for Anonymous Class.

匿名类指南。

  1. Anonymous class is declared and initialized simultaneously.

  2. Anonymous class must extend or implement to one and only one class or interface resp.

  3. As anonymouse class has no name, it can be used only once.

  1. 匿名类同时声明和初始化。

  2. 匿名类必须扩展或实现为一个且仅一个类或接口。

  3. 由于匿名类没有名称,因此只能使用一次。

eg:

例如:

button.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
});

回答by Hazhir

One of the major usage of anonymous classes in class-finalization which called finalizer guardian. In Java world using the finalize methods should be avoided until you really need them. You have to remember, when you override the finalize method for sub-classes, you should always invoke super.finalize()as well, because the finalize method of super class won't invoke automatically and you can have trouble with memory leaks.

匿名类在类终结中的主要用途之一,称为终结器监护人。在 Java 世界中,应该避免使用 finalize 方法,直到您真正需要它们为止。你必须记住,当你覆盖子类的 finalize 方法时,你也应该总是调用super.finalize(),因为超类的 finalize 方法不会自动调用,你可能会遇到内存泄漏的问题。

so considering the fact mentioned above, you can just use the anonymous classes like:

因此,考虑到上述事实,您可以使用匿名类,例如:

public class HeavyClass{
    private final Object finalizerGuardian = new Object() {
        @Override
        protected void finalize() throws Throwable{
            //Finalize outer HeavyClass object
        }
    };
}

Using this technique you relieved yourself and your other developers to call super.finalize()on each sub-class of the HeavyClasswhich needs finalize method.

使用这种技术,您可以减轻自己和其他开发人员调用需要 finalize 方法的super.finalize()每个子类的HeavyClass压力。

回答by raja

new Thread() {
        public void run() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Exception message: " + e.getMessage());
                System.out.println("Exception cause: " + e.getCause());
            }
        }
    }.start();

This is also one of the example for anonymous inner type using thread

这也是使用线程的匿名内部类型的示例之一

回答by user2837260

i use anonymous objects for calling new Threads..

我使用匿名对象来调用新线程..

new Thread(new Runnable() {
    public void run() {
        // you code
    }
}).start();