注意:我发现另一个答案表明Java会将静态方法调用重定向到它自己的类,即使它在子类上被调用,所以我想我需要找到一个Groovy工作 - 周围的伎俩或它不会是可行的。
问题在于:我创建了一个抽象的通用" Launcher"带有" public static void main"的类。这个想法是你扩展它,在你的子类中你注释这样的方法:
@Command("Show an explorere shell")
public dir() {
"explorer".execute()
}
此类的父级有一个经过的主,反映@Command注释,如果方法名称与您的参数匹配,则执行它。
问题在于,我无法弄清楚如何判断实际的实例化类在父的静态主方法中是什么。
我很确定某处有诀窍 - "这个"不会在静力学中工作,堆栈跟踪不包含实际的类,只包含父类,我无法在类或MetaClass对象中找到任何帮助的元信息。
目前,我已经通过将子类的名称硬编码到父母的主要内容来实现这一目标:
public class QuickCli {
public static void main(String[] args} {
(new HardCodedChildClassName())."${args[0]}"()
}
}
我从中削减了很多,但这是一般的想法。我想替换
"new HardCodedChildClassName()"
有一些东西适用于任何扩展此类的类。
鉴于上面的两个代码片段,命令将从命令行执行:
groovy HardCodedChildClassName dir
虽然我不想让所有的@Command方法保持静态但我必须这样做,但是目前我甚至不相信我能做到这一点。
答案 0 :(得分:3)
我不确定这是可能的。无论如何,它可能是一个丑陋的黑客,如果它。我建议使用此备选方案:将main()
设为QuickCli
,而不是使用静态Runnable
入口点。 Groovy将自动创建一个实例,并在启动时调用run()
。
这里的一个小问题是捕获命令行参数。 Groovy通过将它们传递给具有String[]
参数的构造函数来处理它。实例化的类需要此构造函数来捕获args,但在Java中,构造函数不会被继承。幸运的是,Groovy有一个InheritConstructors
注释可以解决这个问题。
以下是一个示例:
class QuickCli implements Runnable {
def args
QuickCli(String[] args) {
this.args = args
}
void run() {
"${args[0]}"()
}
}
@groovy.transform.InheritConstructors
class HardCodedChildClassName extends QuickCli {
@Command("Show an explorere shell")
public dir() {
"explorer".execute()
}
}