我如何在Groovy中获得类似匿名内部类的东西?

dro*_*del 7 groovy

如何在Groovy中定义匿名内部类?我看到了他们应该在Groovy 1.7中支持的引用,我使用的是1.8.

 thread = process.consumeProcessOutput(
   new Appendable() {
     Appendable append(char c) {
       app1.append(c)
       app2.append(c)
       return this
     }

     Appendable append(CharSequence csq) {
       app1.append(csq)
       app2.append(csq)
       return this
     }

     Appendable append(CharSequence csq, int start, int end) {
       app1.append(csq, start, end)
       app2.append(csq, start, end)
       return this
     }
   })
Run Code Online (Sandbox Code Playgroud)

我用这段代码得到一个例外:

Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.UNIXProcess.consumeProcessOutput() is applicable for argument types: (MyClass$1) values: [MyClass$1@19c8ef56]
Run Code Online (Sandbox Code Playgroud)

ata*_*lor 7

这是一个棘手的情况,因为方法必须将对象本身作为一个返回Appendable,并且具有重载的方法名称,这对于groovy map到接口转换不能很好地工作.最简单,最清晰的方法可能是使用匿名内部类,就像在Java中一样.这需要一个合理的当前版本的groovy(1.7或更新我认为):

def testAppendable(Appendable appendable) {
    println "appendable = $appendable"
    appendable.append('a' as char).
               append('b' as char).
               append('c' as char)
}

testAppendable(new Appendable() {
    Appendable append(char c) {
        println "got $c"
        this
    }
    Appendable append(CharSequence csq) {
        this
    }
    Appendable append(CharSequence csq, int start, int end) {
        this
    }
    String toString() { "inner class appendable" }
});
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用Expando带闭合的.这有点尴尬,因为每个方法名称只能在构造函数中初始化一个实现.请注意,省略的任何接口方法都会被赋予一个抛出异常的默认实现.

testAppendable(new Expando(
    append: { char c ->
        println "got $c"
        delegate as Appendable
    },
    toString: { ->
        "expando appendable"
    }
) as Appendable)
Run Code Online (Sandbox Code Playgroud)

编辑:关于你的例子,我不明白为什么它会失败.我的测试几乎完全相同,没有任何问题.签名process.consumeProcessOutput看起来像什么?此外,您可以通过运行来仔细检查该MyClass$1实现.Appendablejavap MyClass$1


Ray*_*yek 0

这适用于最近的靛蓝:

List l=new LinkedList() {
            {
                add(new Integer(1));
                add(new Integer(2));
            }
        };
println l
Run Code Online (Sandbox Code Playgroud)