Groovy 取代静电场

Groovy 取代静电场,groovy,metaprogramming,Groovy,Metaprogramming,Grails提供的CountryTagLib有一个国家(过期)列表 class CountryTagLib { static final ISO3166_3 = [ "scg":"Serbia and Montenegro", "zmb":"Zambia" ] } 我想更新这张地图,将“塞尔维亚和黑山”条目替换为每个塞尔维亚和黑山的条目 更新 我不能这么做,或者是因为ISO3166_3的内容被复制到了静态初始值设定项中的其他变量中 static

Grails提供的
CountryTagLib
有一个国家(过期)列表

class CountryTagLib {
    static final ISO3166_3 = [
        "scg":"Serbia and Montenegro",
        "zmb":"Zambia"
    ]
}
我想更新这张地图,将“塞尔维亚和黑山”条目替换为每个塞尔维亚和黑山的条目

更新 我不能这么做,或者是因为
ISO3166_3
的内容被复制到了静态初始值设定项中的其他变量中

static {
    ISO3166_3.each { k, v ->
        COUNTRY_CODES_BY_NAME[v] = k
    }
}

我需要在这个静态初始值设定项运行之前执行修改ISO3166_3的代码。我不认为有任何方法可以实现这一点,因此我只剩下一个令人不快的选项:将整个
CountryTagLib
复制粘贴到自定义taglib中,并在其中修改
ISO3166_3
。我还必须更改每个
以使用我的标记。我真的不想这样做….

为什么你不直接访问地图?该字段为
final
,这意味着您不能修改字段本身,但不能修改其内容:

你不能这样做:

CountryTagLib.ISO3166_3 = xxxx // this will fail (final)
但这应该是可行的:

CountryTagLib.ISO3166_3.remove('scg')
..etc...

你为什么不直接访问地图?该字段为
final
,这意味着您不能修改字段本身,但不能修改其内容:

你不能这样做:

CountryTagLib.ISO3166_3 = xxxx // this will fail (final)
但这应该是可行的:

CountryTagLib.ISO3166_3.remove('scg')
..etc...

严的方法是国际海事组织最干净的方法,但供将来参考;在元类重写中链接回替换方法的一种方法是将旧方法存储在某个位置,然后在新方法中调用该方法:

class CountryTagLib {
    static final ISO3166_3 = [
        "scg":"Serbia and Montenegro",
        "zmb":"Zambia"
    ]
}

// Get a handle to our old static getISO3166_3 method
def originalGetter = CountryTagLib.metaClass.getStaticMetaMethod( 'getISO3166_3', [] as Object[] )
CountryTagLib.metaClass.static.getISO3166_3 = {
    // Call the old method, and manipulate the map it returns
    originalGetter.invoke( delegate, null ).with {
      remove('scg')
      put( 'srb', 'Serbia' )
      put( 'mon', 'Montenegro' )
      it
    }
}

严的方法是国际海事组织最干净的方法,但供将来参考;在元类重写中链接回替换方法的一种方法是将旧方法存储在某个位置,然后在新方法中调用该方法:

class CountryTagLib {
    static final ISO3166_3 = [
        "scg":"Serbia and Montenegro",
        "zmb":"Zambia"
    ]
}

// Get a handle to our old static getISO3166_3 method
def originalGetter = CountryTagLib.metaClass.getStaticMetaMethod( 'getISO3166_3', [] as Object[] )
CountryTagLib.metaClass.static.getISO3166_3 = {
    // Call the old method, and manipulate the map it returns
    originalGetter.invoke( delegate, null ).with {
      remove('scg')
      put( 'srb', 'Serbia' )
      put( 'mon', 'Montenegro' )
      it
    }
}