Java的这一新增功能难以实现吗?

时间:2012-07-29 21:51:57

标签: java compiler-construction decorator

我经常希望能够正确地装饰java类,即向它们添加行为。我知道来自红宝石的混合物,我知道它们会非常混乱。

我提出了这样一种语言结构的理论思想:

package org.test.decorator;

public decorator ListPatch<E> extends List<E> {
    public E last() {
        return this.get(this.size() - 1);
    }
}

this可以访问List和Decorator本身的公共成员。

然后在课堂上我可以使用:

package org.test.decorator;

decoration org.test.decorator.ListPatch;

public MyClass {
    public void foo() {
        List<String> list = Lists.newArrayList();
        list.add("test");
        System.out.println(list.last());
    }
}

我对编译器知之甚少,所以我想知道这样的事情是否可行。如果它确实会有所改善。

3 个答案:

答案 0 :(得分:2)

当然,这是可能的。

Scala编译为字节码(并且具有从Scala类到字节码类的相当直接的映射)并支持mixins这一事实证明了这一点。

以下是您的示例代码在Scala语法中的外观:

class ListTest {

    // ...

}

trait ListPatch {
    def last {
        // ...
    }
}

object Main {
    def main(args: Array[String]) {
        val list = new ListTest() with ListPatch;
        list.add("test")
        println(list.last)
    }
}

Scala通过添加组成Main$$anon$1ListTest的腋下类ListPatch来编译它。

Java开发人员的座右铭一直是(并且可能永远都是)“如果有疑问,请将其删除。”尽管如此。

相关问题:

答案 1 :(得分:1)

不是你的问题的答案,但你可以通过控制/依赖注入的反转来解决这个问题(就像你在代码中所做的那样)

基本上是: 不要使用“new ArrayList()”而是使用像“injector.new(ArrayList.class)”这样的工厂。此注入器现在可以覆盖所需的类并返回一个Object,该Object扩展了使用您的方法修饰的ArrayList。

答案 2 :(得分:1)

您的想法听起来很像Extension methods in C#

  

扩展方法使您可以向现有类型“添加”方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型。

在C#中你会把你的例子写成:

public static class ListExtensions
{
    public E Last(this List<E> list)
    {
        return list[list.Count - 1];
    }
}

像这样使用它:

List<String> list = new List<String>();
list.Add("test");
Console.WriteLine(list.Last());

因此,从设计角度来看,它当然可以设计和添加。但是,在向现有语言添加内容时会有其他一些注意事项,例如语法冲突,向后兼容性,边缘情况,设计和编码成本与其提供的好处。

Eric Lippert在C#中有a great blog about Extension Properties(扩展方法的自然扩展),在第二部分中,他强调了影响为什么产品X没有Y功能的一些方面?,我肯定也适用于Java及其开发。