【问题标题】:"This" in anonymous inner object匿名内部对象中的“这个”
【发布时间】:2014-08-10 21:47:01
【问题描述】:

我想写一个 groovy 版本的这个 java 代码:

class HelloWorld {
    static main(args) {
        def server = Server.builder()
                .setHandler(new HttpHandler() {
                      public void handle(final Ev ev){
                          ev.dispatch(this)
                      }
                    }
                }).build()
        server.start()
    }
}

我生成的 groovy 代码是:

class HelloWorld {
    static main(args) {
        def server = Server.builder()
                .setHandler(new HttpHandler() {
                      public void handle(final Ev ev){
                          ev.dispatch(this)
                      }
                    }
                }).build()
        server.start()
    }
}

问题来自 ev.dispatch(this):ev.dispatch 需要一个 HttpHandler 对象,但 groovy 中的“this”,即使是类型转换,也不会产生 HttpHandler 对象。

我尝试将“this”替换为“delegate”或“owner”,但没有任何改变。

我尝试用闭包替换 anonim 内部类,但没有不同的 esit:

class HelloWorld {
    static main(args) {
        def server = Server.builder()
                .setHandler({ ev -> 
                      public void handle(final Ev ev){
                          ev.dispatch(this)
                      }
                    } as HttpHandler
                ).build()
        server.start()
    }
}

有什么建议吗?? (使用 groovy 2.3.6)

【问题讨论】:

  • "...但在 groovy 版本中,这指的是 HelloWorld 外部对象。" - 这几乎是不可能的。在您的示例中没有创建 HelloWorld 的实例。你确定这就是this 所指的吗?
  • 它是指作为 HelloWorld 实例的对象,还是评估 HelloWorld 类(就像 HelloWord.class 一样)?
  • 我已经运行了描述中发布的第一个 Groovy 示例(在修复了不匹配的花括号之后),this 不是指HelloWorld 的实例,this 指的是HelloWorld$1,这是一个匿名内部类,它是HttpHandler 的一个实例,this 应该在那里引用。
  • @JeffScottBrown 你是对的 println "this" 与 HelloWorld$1 相呼应。但是,如果我尝试将其强制转换为 HttpHandler,我会收到此异常:无法将具有类 'java.lang.Class' 的对象 'class mypkg.Underdog$1' 强制转换为类 'mypkg.HttpHandler'
  • 您确实应该更改“但在 groovy 版本中这指的是 HelloWorld 外部对象”的措辞,因为您让人们花费(浪费)他们的时间来调查没有发生的事情。我会自己编辑它,但我认为政策是编辑其他人的问题不应该改变问题的意图。

标签: java groovy closures inner-classes anonymous-class


【解决方案1】:

以下有2个问题:

class HelloWorld {
    static main(args) {
        def server = Server.builder()
                .setHandler(new HttpHandler() {
                      public void handle(final Ev ev){
                          ev.dispatch(this)
                      }
                    }
                }).build()
        server.start()
    }
}

一个是匿名内部类定义中的大括号不匹配。当应该只有 2 个时,连续有 3 个右花括号 (})。

另一个似乎是 Groovy 中的错误。见https://jira.codehaus.org/browse/GROOVY-7020

【讨论】:

  • 谢谢斯科特。更正了问题中的大括号问题。那么可能是一个 groovy 错误?谢谢你。我会关注错误报告。与此同时,我已经将匿名内部类声明为一个常规的、单独的文件、类,并且一切正常。何我可以在修复错误后以更简洁的方式在 groovy 中编写它。谢谢
【解决方案2】:

在 Groovy 中,this, owner and delegate usually mean the same thing 在闭包内。

Groovy(讽刺的是?)不允许您通过关键字匿名引用匿名闭包。您必须在所有者的范围内命名闭包,然后您可以通过该名称引用它。如果您将其声明为所有者中的字段,那么您应该能够直接自引用,但在这种情况下,您将在静态方法中声明它,因此这可能行不通。相反,您可以只设置handler.delegate = handler,然后在闭包内使用delegate 进行自我引用。

另外,我认为您不应该在闭包中声明方法——您只需直接编写代码即可。我想这就是你想要的:

class HelloWorld {
    static main(args) {
        def handler = { ev -> 
            ev.dispatch(delegate)
        } as HttpHandler
        handler.delegate = handler
        def server = Server.builder()
                .setHandler(handler).build()
        server.start()
    }
}

这扼杀了使用闭包应该给您带来的一些简洁性,但显然这就是您所坚持的。

【讨论】:

  • 你的代码给了我这个异常 groovy.lang.MissingPropertyException: No such property: handler for class: mypkg.Underdog
  • @FabianoTaioli - 你说得对——我忽略了它在方法中声明的事实。 Groovy 的闭包语义真的很奇怪。我改变了我的答案——希望它现在对你有用。
  • 得到了这个 -> groovy.lang.MissingPropertyException:没有这样的属性:类的委托:com.sun.proxy.$Proxy4
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-02
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2011-09-19
  • 1970-01-01
相关资源
最近更新 更多