代码之家  ›  专栏  ›  技术社区  ›  cretzel

如何在执行groovyshell之后撤消元类更改?

  •  10
  • cretzel  · 技术社区  · 17 年前

    例如,如果我执行一个groovy脚本,它修改了string元类,则添加一个方法foo()

    GroovyShell shell1 = new GroovyShell();
    shell1.evaluate("String.metaClass.foo = {-> delegate.toUpperCase()}");
    

    当我在此之后创建一个新的shell并执行它时,更改仍然存在

    GroovyShell shell2 = new GroovyShell();
    Object result = shell2.evaluate("'a'.foo()");
    

    在执行groovyshell之后,是否有方法撤消所有的元类更改?我试过

    shell1.getClassLoader().clearCache();
    

    和

    shell1.resetLoadedClasses();
    

    但这并没有改变。

    3 回复  |  直到 10 年前
        1
  •  12
  •   Christoph Metzendorf    16 年前

    你可以使用

    GroovySystem.metaClassRegistry.removeMetaClass(String.class);
    

    还原对字符串元类所做的所有更改。

    或者,您只能更改某个字符串实例的元类,因此不会影响字符串的所有实例。

        2
  •  2
  •   Sudhir N    10 年前

    你也可以使用Meta CaseRealCube。

    在做一些元类改变之前,你可以做

    MetaClassRegistryCleaner registryCleaner = MetaClassRegistryCleaner.createAndRegister()
    GroovySystem.metaClassRegistry.addMetaClassRegistryChangeEventListener(registryCleaner)
    

    当您想将元类更改重置为之前的状态时。

    你可以做

    registryCleaner.clean()  
    GroovySystem.metaClassRegistry.removeMetaClassRegistryChangeEventListener(registryCleaner)
    

    通过这种方式,你可以重置在持续期间所做的所有元类改变。

        3
  •  0
  •   user340535    14 年前

    我意识到这是一个比较老的问题,但这是谷歌搜索的第一个结果。

    我选择的解决方案是将Groovy放入一个新的子文件夹中(通过使用神经丛),因此当脚本完成时,将处理子字符串(因此对子表达式的任何更改也将被处理)。