java - 扩展接口(interface)与通过匿名类实例化

标签 java interface runnable anonymous-class

注意:我知道这与许多其他问题非常接近。然而,我还没有看到任何与 Android 的 OnClickListener 接口(interface)无关的内容。我问的是一般意义上的。

我理解通过匿名类实例化接口(interface)之间的区别...... 啦:

private final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        draw();
    }

};

...并扩展接口(interface)。

public class ClassyClass implements Runnable {
    ...
    //do other cool stuff here
    ...
    @Override
    public void run() {
        draw();
    }
    ...
    //and more here
    ...

}

但是,除了 OnClickListener 等接口(interface)的明显好处之外,这两个选项还有什么强大的优势吗?

我认为扩展它是显而易见的选择,因为您已经在创建该对象 - 无需重复工作。这是正确的吗?

我问的是一般意义上的问题,但是,由于我目前正在使用Runnable,我很想知道它是否从这两个选项中看到了优势。

最佳答案

这是一个显示主要差异的示例。虽然有点做作,但只是为了说明。

这是一个匿名版本:

class PrintBuilder {
    List<Runnable> printers = new LinkedList<>();

    List<Runnable> get() {
        return printers;
    }

    PrintBuilder add(final String line) {
        printers.add(new Runnable() {
            public void run() {
                System.out.println(line);
            }
        });

        return this;
    }
}

这是一个嵌套版本:

class PrintBuilder {
    List<Printer> printers = new LinkedList<>();

    PrintBuilder add(String line) {
        printers.add(new Printer(line));
        return this;
    }

    List<Printer> get() {
        return printers;
    }

    static class Printer implements Runnable {
        String line;

        Printer(String line) {
            this.line = line;
        }

        public void run() {
            System.out.println(line);
        }
    }
}

所以你可以看到主要的区别是:

  • 匿名类是内部类,它具有对封闭实例的隐式引用。

特别是,在上面的示例中,PrintBuilder 会泄漏,直到内部 Runnable 对象死亡为止。在第二个示例中,Runnable 类是静态的,因此不存在此问题。

  • 匿名类稍微短一些。

匿名类不需要字段和构造函数,因为它们是隐式的。

  • 代码的组织方式存在巨大差异。

匿名类是在实例化的地方声明的,如果匿名类不是很短,这可能会对封闭类的布局造成很大的破坏。另一方面,如果匿名类很短,那么类似函数的语法就很好。

此外,所有类都会增长,根据我的经验,当匿名类变得太大时,这可能会变成一种气味。匿名类也更难以重构为顶级类。

关于java - 扩展接口(interface)与通过匿名类实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22728932/

相关文章:

java - WIndows 10下maven安装问题

java - 带 Spring Boot : Upload MultipartFile and Json object as parameters 的 Spring 支架

json - golang 将接口(interface)数组转换为字符串

java - Loop 中使用的接口(interface)实现

java - 如何使可运行程序提前终止

java - 奇怪的结果(java事件处理代码)

java - 如何在不重启应用程序的情况下通过 Java Web 应用程序反射(reflect)电子表格中的更改?

c# - 为 C# 接口(interface)定义隐式和显式强制转换

java - 将 Java ThreadFactory 创建的对象的所有引用置为 null 的方法

java - 停止并重新运行自身内部的线程