[Groovy] this 语义的陷阱

[Groovy] this 语义的陷阱,第1张

概述groovy 中 this 的语义有问题。下面的代码会报异常,说 secret2 方法找不到: new Sub().doSomething()class Parent { def doSomething() { secret().secret2() } private def secret() { println "secret" this } groovy 中 this 的语义有问题。下面的代码会报异常,说 secret2 方法找不到:
new Sub().doSomething()class Parent {	def doSomething() {		secret().secret2()	}		private def secret() {		println "secret"		this	}		private def secret2() {		println "secret 2"		this	}}class Sub extends Parent {	def doSomething() {		super.doSomething()	}}

将 Parent#doSomething() 修改一下,打印出 secret() 的返回值类型后得到:
	def doSomething() {		println secret()	}

输出:
引用 secret
class Sub

this 指向的是子类型。所以不要把 chaining 用在 private 方法上。因为子类型无法访问到父类型的 private 方法,返回 this 就会引起子类型报错。


在 Java 试验的结果是 println 显示 this.getClass() 为 Sub,与上面的 Groovy 代码结果一致。但是 Java 下调用是成功的。也就是说 Java 并不是像表面上 println 显示的那样简单地直接使用 Sub 的实例去调用 secret2(),而是隐式用的 Parent 实例去调用 secret2()。Groovy 在动态调用方法时没有考虑到这点,直接用 "this" 去调,导致找不到 secret2() 这个函数。

补2
这个问题现在看来比较严重。如果父类中的私有方法调用了另一个私有方法,那么子类如果在运行时用到了这个父类的私有方法,就会抛异常。示例:
new Sub().doSomething()class Parent {	def doSomething() {		secret()	}		private def secret = {		secret2()	}		private def secret2 = {		println "secret 2"	}}class Sub extends Parent {	def doSomething() {		super.doSomething()	}}

所以,父类的私有方法不能调用其它的私有方法。

补3
在 codehaus 上找到了与这个问题本质上一样的 BUG report: http://jira.codehaus.org/browse/GROOVY-3073。Jochen Theodorou 说这是因为 Groovy 当前的 MOP(Meta Object Protocol)不支持造成的。预计会在 Groovy 2.0 中解决这个问题。 总结

以上是内存溢出为你收集整理的[Groovy] this 语义的陷阱全部内容,希望文章能够帮你解决[Groovy] this 语义的陷阱所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1261406.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存