Как заставить класс Groovy выглядеть как код Map to Java без явной реализации интерфейса Map
Я хочу реализовать пользовательский класс, подобный Map, в котором большая часть функциональности делегирована вложенному экземпляру делегата Map. И я хочу, чтобы этот класс выглядел как карта "истинных" Java-классов. Поэтому я попытался сделать следующее:
class ConfigurationMap implements Map {
def inner = [:]
def methodMissing(String methodName,methodArgs) {
return inner.invokeMethod(methodName,methodArgs)
}
// my methods here
...
И, конечно, это не работает:-( Groovy требует, чтобы класс реализовал методы интерфейса Map, несмотря на то, что во время выполнения они будут обрабатываться missedMissing(). Если я удалю implements
пункт:
class ConfigurationMap {
def inner = [:]
def methodMissing(String methodName,methodArgs) {
return inner.invokeMethod(methodName,methodArgs)
}
это работает для Groovy (то есть экземпляр действительно ведет себя как карта), но я не могу использовать его как карту из кода Java:
ConfigurationMap cm = ConfigParser.parseConfig("foo.cfg");
assertEquals(0,cm.size()); // size() method is not defined :-(
И мой совет относительно того, как я могу сделать свой класс коротким (то есть не реализовывать Map явно) и при этом заставить класс выглядеть как Map to Java?
1 ответ
Я думаю, что если вы используете @Delegate
примечание, что скомпилированный байт-код будет работать должным образом из Java.
class ConfigurationMap implements Map {
@Delegate Map inner = [:]
def myMethod() {
return true
}
}
ConfigurationMap cm = new ConfigurationMap()
cm.foo = "bar"
assert "bar" == cm.foo
assert true == cm.myMethod()