25

有一个内部问题,为什么 java 匿名类不能同时实现和子类化?或者仅仅是因为语法?

4

5 回答 5

29

有一个内部问题,为什么 java 匿名类不能同时实现和子类化?

由于句法原因,我相信它是 99%。类型参数甚至支持交集类型( <T extends InterfaceX & InterfaceY>),所以我认为这样的特性不会引入任何矛盾或复杂性。

例如,像这样的表达式new (InterfaceX & InterfaceY)() { ... }可以编译成类似的东西

interface InterfaceXandY extends InterfaceX, InterfaceY {}
... new InterfaceXandY() { ... }

没有添加此类功能的原因很可能是因为它是一种罕见的用例,有一个简单的解决方法。


在一个有点相关的说明上。例如,您可以让 lambda 实现Serializable

Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");

请参阅如何序列化 lambda?

于 2011-11-24T09:26:28.450 回答
6

发现了一个关于这个的黑客

在你的文件底部创建一个接口,扩展你想要实现的所有接口,然后创建一个匿名类来实现它。

于 2011-10-30T00:25:56.860 回答
6

仅语法,所谓的匿名类是 100% 普通类。你可以通过使用 java.lang.reflect.Proxy 和 InvocationHandler 来获得一个时髦的结果,这将是最肮脏的方法。

更简单的方法包括在方法中声明类并添加“实现”,

于 2011-01-23T13:59:22.607 回答
6

提供匿名类作为一种快速简洁地构建“一次性”类的方法。您的问题表明您正在尝试以多种方式使用您的匿名类(至少一个接口,一个扩展)。在这种情况下,如果您将该匿名类提升为完整类,它将更具可读性和可维护性。

这也可以通过更好地管理类的封装来避免意外的副作用。

于 2011-01-23T14:03:59.640 回答
4

根据詹姆斯·高斯林的说法

闭包最初被排除在 Java 之外更多是因为时间压力。在 Java 的早期,缺少闭包是相当痛苦的,因此内部类诞生了:这是一种令人不安的折衷方案,它试图避免一些棘手的问题。但在许多设计问题中很正常,简化并没有真正解决任何问题,他们只是移动了它们。

有趣的是,既然 lambda 表达式和闭包被添加到 Java 中,而且这次使用了不同于内部类的东西,我们可以动态定义一个由多个接口组成的对象,前提是第二个接口是标记接口。

interface Bar {
   default String getName() { return "Bar"; }
}

Object o = (Comparable<Integer> & Bar) (x,y) -> x > y ? x : y;
Bar b = (Bar) o;
System.out.println(b.getName()); //Bar

这可以在我最新的 JDK 8 版本(2013 年 3 月 12 日)中完美编译和运行。所以,看起来他们这次已经对这个问题给予了更多的思考。

于 2013-03-12T16:55:50.273 回答