【问题标题】:When to use anonymous classes? [closed]何时使用匿名类? [关闭]
【发布时间】:2015-11-30 11:06:47
【问题描述】:

我遇到了一些包含匿名类的代码。我之前没有遇到过匿名课程,所以我对它们进行了一些研究。

我的主要兴趣领域是 java,所以我检查了Oracle's tutorial of anonymous classes. 我了解机制并看到示例的重点,但在我看来,使用匿名类会使代码难以阅读并且可能会引起很多头痛。

是否存在不可避免使用匿名类或建议使用匿名类而不是命名类的情况?

【问题讨论】:

  • 文档说:匿名类可以让你的代码更简洁。它们使您能够同时声明和实例化一个类。它们类似于本地类,只是它们没有名称。如果您只需要使用一次本地类,请使用它们。
  • 我完全同意 anonymousinner 类可以使代码不可读和混乱,但它们也可以在很少需要的情况下澄清很多。它们是您手中的工具,请明智地选择。
  • 匿名内部类是众所周知的双刃剑之一。

标签: java oop anonymous-class


【解决方案1】:

是否存在不可避免使用匿名类的情况

不,您总是可以只使用私有内部类而不是匿名类。


使用匿名类会使代码难以阅读,并且会让人头疼

这在很大程度上取决于您如何使用匿名类。考虑以下示例:

new Thread(new Runnable() {
    @Override
    public void run() {
        // do something
    }
}).start();

在本例中,您创建了一个由线程运行的 Runnable。如果您不使用匿名类,则必须按如下方式编写:

private class SomeClass implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub

    }
}

并将其用作:

new Thread(new SomeClass()).start();

在第一种可能性中,您可以直接看到该线程在做什么,在第二种可能性中,您首先必须找到此处使用的类。


匿名类的另一个优点。您可以执行以下操作:

// define some constant which can be used in the anonymous class:
final String someStr = "whatever";

new Thread(new Runnable() {
    @Override
    public void run() {
        // use the String someStr directly
        System.out.println(someStr);
    }
}).start();

您可以使用在定义匿名类的代码中声明的常量。如果您要使用私有内部类,则必须将这些常量提供给类的构造函数才能使用它们!

【讨论】:

    【解决方案2】:

    您总是可以通过隐式定义新类来避免使用匿名类。但是在某些情况下,最好使用匿名类。考虑以下示例:

    void main() {
       new Thread(new Runnable(){
          public void run() {
            System.out.println("Hello world");
          }
       }).start();
    }
    

    上面的代码 sn-p 比定义新类更具可读性和更短。

    public class MyRunnable implements Runnable {
       public void run() {
         System.out.println("Hello world");
       }
    }
    
    
    void main() {
       new Thread(new MyRunnable()).start();
    }
    

    在 Java 8 中,labmda 在某些情况下可以用来代替匿名类

    Runnable task = () -> { System.out.println("hello world"); };
    new Thread(task).start();
    

    【讨论】:

    • Lambdas 与 Anonymous 类的概念无关,而是与 Functional interface(只有一个方法的接口)相关。
    • @Prim 它们非常相关,但并不总是可以互换的。
    • @biziclop 是的,但答案是"In Java 8 labmda can be used instead of anonymous class",这是不正确的。只有当它是一个实现功能接口的匿名类时才是真的
    【解决方案3】:

    是否存在不可避免使用匿名类的情况...

    没有。您总是可以为此定义一个命名类。匿名类的重点是在您只需要使用一次类的情况下使代码更加简洁和紧凑。

    建议使用它们而不是命名类?

    这取决于正在创建的类的上下文。

    如果您正在实现只有一个函数(即 Runnable)的接口,那么使用 lambda 表达式而不是匿名类不是一个糟糕的选择。 lamba expression

    【讨论】:

      猜你喜欢
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      相关资源
      最近更新 更多