为什么匿名类不能直接实现多个接口?仅仅因为语法还是有其他原因?

时间:2011-01-23 13:53:14

标签: java inner-classes anonymous-class

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

5 个答案:

答案 0 :(得分:25)

  

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

由于语法原因,我认为这是99%。类型参数甚至支持intersection types<T extends InterfaceX & InterfaceY>),所以我认为这样的功能不会引入任何矛盾或复杂情况。

new (InterfaceX & InterfaceY)() { ... }这样的表达式可以编译成类似

的表达式
interface InterfaceXandY extends InterfaceX, InterfaceY {}
... new InterfaceXandY() { ... }

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


有点相关的说明。 可以通过执行

让lambda实现Serializable实例
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");

请参阅How to serialize a lambda?

答案 1 :(得分:6)

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

更简单的方法包括在方法中声明类并只添加'implements',

答案 2 :(得分:6)

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

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

答案 3 :(得分:6)

发现了一个黑客攻击

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

答案 4 :(得分:4)

According to James Gossling

  

由于时间原因,闭包最初被排除在Java外面   压力比什么都重要。在Java的早期缺乏   关闭是相当痛苦的,因此内部阶级诞生了:a   试图避免一些努力的不舒服的妥协   的问题。但正如在许多设计问题中一样正常,简化   没有真正解决任何问题,他们只是感动了它们。

有趣的是,现在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日)中编译并运行完美。所以,这次看起来他们已经更多地考虑过这个问题。