Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >覆盖已通过expandoMetaClass添加的方法

覆盖已通过expandoMetaClass添加的方法
EN

Stack Overflow用户
提问于 2016-10-07 05:47:14
回答 1查看 68关注 0票数 0

我很难理解GroovyClassLoader缓存是如何与扩张性方法工作的。

特别是,我期望下面的代码为每次调用Number.test()提供不同的输出,但事实并非如此。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int i = 1

Number.metaClass.test = {
  return "A string"
}
println i.test()

println GroovySystem.metaClassRegistry.getMetaClass(Number.class)
Number.metaClass = null
println GroovySystem.metaClassRegistry.getMetaClass(Number.class)

Number.metaClass.test = {
  return "Another String"
}
println i.test()

println GroovySystem.metaClassRegistry.getMetaClass(Number.class)
GroovySystem.metaClassRegistry.removeMetaClass(Number.class)
println GroovySystem.metaClassRegistry.getMetaClass(Number.class)

Number.metaClass.test = {
  return "Yet another String"
}
println i.test()

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A string
groovy.lang.ExpandoMetaClass@3571b748[class java.lang.Number]
groovy.lang.MetaClassImpl@7748410a[class java.lang.Number]
A string
groovy.lang.ExpandoMetaClass@37f1104d[class java.lang.Number]
groovy.lang.MetaClassImpl@55740540[class java.lang.Number]
A string

编辑:

我尝试了更多的东西。看来我的系统表现得很奇怪。考虑到以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def i = 1

i.class

Number.metaClass.test = {
  return "A string"
}
println i.test()

Number.metaClass = null
Number.metaClass.test = {
  return "Another String"
}
println i.test()

GroovySystem.metaClassRegistry.removeMetaClass(Number.class)
Number.metaClass.test = {
  return "Yet another String"
}
println i.test()

当我在我的系统上执行它时,它按预期的方式工作(在输出中得到3个不同的字符串),但是如果我评论被认为无用的A string,它会失败(3x i.class )。

但是,如果我在groovy-line e.apppot.com上执行它,它就会给出预期的输出,不管有没有这一行.

我有点不知所措。

EN

回答 1

Stack Overflow用户

发布于 2016-10-07 06:44:21

创建int i = 9时,它使用当前的Number.metaClass创建一个对象。它接受创建一个新方法(read Number.metaClass.test = { "A string" }),但不允许重载已经存在的方法。您可以更改对象的元类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int i = 1

Number.metaClass.test = { "A string" }
assert i.test() == "A string"

Number.metaClass = null

i.metaClass.test = { "Another String" }
assert i.test() == "Another String"

GroovySystem.metaClassRegistry.removeMetaClass(Number.class)
assert i.test() == "Another String"

i.metaClass.test = { "Yet another String" }
assert i.test() == "Yet another String"

在我看来,需要调用i.class就像个窃听器.看看jira,我看到了一些未解决的和打开的bug。我觉得你的看起来和这些很像:

在Java类metaClass上重写方法直到实例metaClass更改后才生效:https://issues.apache.org/jira/browse/GROOVY-5065 使用metaClass覆盖类层次结构中的方法不像预期的那样工作:https://issues.apache.org/jira/browse/GROOVY-3942 通过.metaClass重写方法的行为不一致:https://issues.apache.org/jira/browse/GROOVY-6847 删除metaClass方法:https://issues.apache.org/jira/browse/GROOVY-4189

如果您考虑一个具体的类,那么我的答案的第一部分起作用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Echo {}
Echo.metaClass.test = { "A string" }
def i = new Echo()
assert i.test() == "A string"

Echo.metaClass = null
Echo.metaClass.test = { "Another String" }
assert i.test() == "A string"

i.metaClass.test = { "Another String" }
assert i.test() == "Another String"

i.metaClass.test = { "Yet another String" }
assert i.test() == "Yet another String"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39918834

复制
相关文章
linux可执行文件添加到PATH环境变量的方法
linux命令行下面执行某个命令的时候,首先保证该命令是否存在,若存在,但输入命令的时候若仍提示:command not found 这个时候就的查看PATH环境变量的设置了,当前命令是否存在于PATH环境变量中 #查看PATH: echo $PATH 举例说,命令 composr 在/usr/loca/bin 但执行的时候提示: -bash: composr: command not found 这个时候,通过echo $PATH,,发现composer并未在PATH环境变量中有设置,这个时候就需要把co
joshua317
2018/04/16
3.3K0
设置java环境变量path_配置java环境变量path怎么设置[通俗易懂]
只需要在path中增加%JAVA_HOME%\bin; 即可。完整的JDK安装及环境变量配置如下:
全栈程序员站长
2022/06/24
2.5K0
添加环境变量export PATH
这里可以看到如果使用rpi_4_32b_defconfig则使用32位的交叉编译工具:arm-linux-gnueabihf-gcc。如果使用rpi_4_defconfig则使用64位的交叉编译工具:aarch64-linux-gnu-gcc。遴选真题(这里总结的教训是:做之前多百度,因为不知道rpi_4_defconfig需要64位的交叉编译工具而失去无数头发)。这里我使用的是64位的。下载aarch64-linux-gnu-gcc:
用户7737280
2021/11/27
1.6K0
在Linux上面装jdk, Tomcat软件,一步一步带你安装
以上的local文件夹下就有一个jdk的文件夹,里面就是jdk的东西了,我们就解压成功了
一写代码就开心
2021/08/05
1.2K0
在Linux上面装jdk, Tomcat软件,一步一步带你安装
【从零开始学习Go语言】二.Go语言的安装
到此golang的基本配置就好了,然后就是基本使用了,这里贴上你的第一个程序代码,试试可以跑起来不?
一只特立独行的兔先生
2020/04/02
5.1K0
Mac搭建Spark环境
版权声明:本文为博主-姜兴琪原创文章,未经博主允许不得转载。 https://blog.csdn.net/jxq0816/article/details/89518847
week
2019/05/10
3.6K0
Mac搭建Spark环境
Linux中的环境变量PATH
一、介绍 在讲环境变量之前,先介绍一下命令which,它用于查找某个命令的绝对路径,示例如下: 在上面的示例中,用which查到rm命令的绝对路径为/usr/bin/rm。 那么问题来了:为什么我们使
Zoctopus
2018/06/04
3.3K0
Java JDK path环境变量配置
注意:这里一旦填写配置路径之后,jdk的文件路径最好不要再更改,否则配置的该变量会失效。
timerring
2022/09/27
1.1K0
Java JDK path环境变量配置
Java环境变量PATH和CLASSPATH
Java开发中常用到环境变量的配置,下面简单介绍下Java中经常配置的环境变量:PATH和CLASSPATH。
全栈程序员站长
2022/06/24
4K0
Java环境变量PATH和CLASSPATH
Cygwin本地安装版
cygwin本地安装版离线即可安装,使用十分方便,适合linux、安卓平台软件开发与测试时使用,倍受行业人员和学者们的青睐.
云深无际
2020/08/12
3.3K0
Cygwin本地安装版
【说站】java环境变量配置path
administrater用户变量只针对administrater用户使用,系统变量所有的用户都可以使用。
很酷的站长
2022/11/23
8400
【说站】java环境变量配置path
【从零开始学习Go语言】二.Go语言的安装
在前一篇文章有介绍过,go语言是google维护与更新,开发人员也都是在谷歌工作的人员,可能都会担心众所周知的防火墙,之前确实被屏蔽了,想要下载的话,可以通过此地址进行下载 —传送门
一只特立独行的兔先生
2020/03/25
4.2K0
【从零开始学习Go语言】二.Go语言的安装
大数据必学Java基础(四):安装notepad++,配置path环境变量
将命令所在的路径配置到path中去,就相当于在计算机中“注册”了一样,以后找这个命令,会直接去你配置的路径下寻找。
Lansonli
2022/07/01
5910
大数据必学Java基础(四):安装notepad++,配置path环境变量
[Linux] /etc/profile和~/.bashrc与PATH环境变量
我遇到的现象是第一次登录是ubuntu用户 ,sudo -s 切换到root用户后 , 新增的path环境变量不生效
唯一Chat
2022/01/05
8200
第7节 Go语言环境搭建
当然你也可以登录Golang的国内网站:https://golang.google.cn/
小尘哥
2019/05/28
1.2K0
Java开发环境系列:JDK安装及环境变量设置(windows)
官网地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html
架构师小跟班
2019/08/06
1.5K0
Java开发环境系列:JDK安装及环境变量设置(windows)
Mac 设置环境变量的位置、查看和添加PATH环境变量
如果输出的是:bash,sh,zsh,那么你的用的可能就是Bourne Shell的一个变种。
星宇大前端
2022/05/06
6.8K0
点击加载更多

相似问题

VueJS:如何在contentEditable div中动态嵌入contentEditable组件

11

标签组件不会使用BackSpace - React本机删除

11

Tinymce contenteditable和backspace按钮

18

更新使用Fluent NHibernate映射的组件时避免删除并重新插入

22

contenteditable div backspace和删除文本节点问题

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文