如何在Groovy中的父静态方法中获取已定义类的名称

时间:2012-06-04 21:02:16

标签: reflection groovy static

注意:我发现另一个答案表明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方法保持静态但我必须这样做,但是目前我甚至不相信我能做到这一点。

1 个答案:

答案 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()    
    }
}