【发布时间】:2015-08-31 00:33:21
【问题描述】:
我的示例是使用 Koshuke args4j's @Option 注释完成的,但同样适用于任何其他方法注释。澄清一下,这个注解可以与字段或设置器一起使用。
它的工作原理如下:
class AnOptionExample {
@Option(name = '-text')
String text
}
还有测试用例:
def 'recognises option from simple object'() {
given:
def options = new AnOptionExample()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-text=whatever')
then:
options.text == 'whatever'
}
现在假设我想在接口级别进行注释,然后重新使用 @Option 定义以及具有多种继承,这将允许为不同的选项集使用不同的接口(简化示例) :
interface Credentials {
@Option(name = '-username')
void setUsername(String username)
@Option(name = '-password')
void setPassword(String username)
String getUsername()
String getPassword()
}
class CredentialsImpl implements Credentials {
String username
String password
}
显示失败的测试用例:
def 'does not recognise option from interface'() {
given:
def options = new CredentialsImpl()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-username=John', '-password=qwerty123')
then:
def ex = thrown(CmdLineException)
ex.message == '"-username=John" is not a valid option'
}
嗯,接口的方法注解是不会被继承的。很公平——这就是 Java 的方式,但是 Groovy 呢?以下是一些希望:
class SomeOptionsWithDelegate {
@Delegate(methodAnnotations = true)
final Credentials credentials = new CredentialsImpl()
@Option(name = '-url')
String url
}
还有显示一些奇怪的测试用例:
def 'does recognise option from interface via @Delegate'() {
given:
def options = new SomeOptionsWithDelegate()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-username=John', '-password=qwerty123', '-url=http://auth.plop.com')
then:
with(options) {
username == 'John'
password == 'qwerty123'
url == 'http://auth.plop.com'
}
}
令人惊讶的是@Delegate(methodAnnotations = true) 工作,尽管委托完成的对象实例没有注释 - 只有Credentials 接口有它们。并且没有方法注释继承......哦等等,实际上这就是重点。这似乎是一个小故障。如果CredentialsImpl没有继承接口级别的那些注解,为什么@Delegate能够拾取这些注解?
另一方面,我希望将这样的行为作为一个特性,所以我不需要在这里使用委托,而是像这样:
@InheritInterfaceMethodAnnotations
class SomeOptionsViaInterface implements Credentials {
String username
String password
@Option(name = '-url')
String url
}
上述示例的明显相关测试用例会以与第二个示例相同的方式失败。因此问题是:有没有像我虚构的注释一样的东西 - @InheritInterfaceMethodAnnotations 可用?
考虑到@Delegate 故障,可以实现。由于它似乎是有用的功能,也许有人已经做到了。如果没有,欢迎任何关于如何自己实施它的建议。
【问题讨论】:
标签: inheritance methods groovy interface annotations