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

标签 reflection groovy static

注意:我发现另一个答案表明 Java 会将静态方法调用重定向到它自己的类,即使它是在子类上调用的,所以我想我需要找到一个 Groovy 解决方法,否则它就不会是可行的。

问题是:我创建了一个带有“public static void main”的抽象通用“Launcher”类。这个想法是你扩展它,并在你的子类中注释这样的方法:

@Command("Show an explorere shell")
public dir() {
    "explorer".execute()    
}

此类的父类有一个 main 函数,它会遍历并反射(reflect) @Command 注释,如果方法名称与您的参数匹配,则执行它。

问题是我不知道如何判断父级静态 main 方法中实际的实例化类是什么。

我很确定某个地方有一个技巧——“this”在静态中不起作用,堆栈跟踪不包含实际的类,只包含父类,而且我找不到任何元信息在有帮助的类或 MetaClass 对象中。

目前,我已经通过将子类的名称硬编码到父类的 main 中来使其工作,如下所示:

public class QuickCli {
    public static void main(String[] args} {
        (new HardCodedChildClassName())."${args[0]}"()
    }
}

我删掉了很多内容,但这是总体思路。我想更换

"new HardCodedChildClassName()"

具有适用于扩展该类的任何类的东西。

鉴于上面的两个代码片段,该命令将从命令行执行:

groovy HardCodedChildClassName dir

虽然我不想将所有 @Command 方法设为静态,但如果必须的话我可以这样做,但目前我什至不相信我可以做到这一点。

最佳答案

我不确定这是否可能。无论如何,如果是的话,这很可能是一个丑陋的黑客行为。我建议采用这种替代方案:不要使用静态 main() 入口点,而是使 QuickCli 成为 Runnable。 Groovy 将自动创建一个实例,并在启动时调用 run()

这里的一个小问题是捕获命令行参数。 Groovy 通过将它们传递给带有 String[] 参数的构造函数来处理此问题。实例化的类需要这个构造函数来捕获参数,但在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()    
    }
}

关于reflection - 如何在 Groovy 的父静态方法中获取已定义类的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10888306/

相关文章:

c# - 检查类/接口(interface)继承的正确方法是什么?

.net - AssemblyVersionAttribute 未由 Assembly.GetCustomAttributesData 找到

c# - 反射.Assembly.CreateInstance(字符串)

c# - Assembly.CreateInstance 和 Activator.CreateInstance 之间的区别?

java - 从 Java 类访问 Config.groovy

c++ - 如何捕获初始化静态成员时抛出的异常

groovy - 方法和属性之间的嵌套闭包解析不同?

Groovy 排序文档

java - JSP 声明中的静态字段

c++ - 模板类中的静态函数