2

注: 子クラスで呼び出された場合でも、Java が静的メソッド呼び出しを独自のクラスにリダイレクトすることを示唆する別の回答を見つけたので、Groovy の回避策を見つける必要があると思います。

問題は次のとおりです。「public static void main」を持つ抽象汎用「Launcher」クラスを作成しました。アイデアは、それを拡張し、子クラスで次のようなメソッドに注釈を付けるということです:

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

このクラスの親には、 @Command アノテーションを反映し、メソッド名がパラメーターと一致する場合にそれを実行する main があります。

問題は、インスタンス化された実際のクラスが親の static main メソッド内にあることを知る方法がわからないことです。

どこかにトリックがあると確信しています-「これ」は静的では機能せず、スタックトレースには実際のクラスが含まれておらず、親クラスのみが含まれており、クラスにメタ情報が見つかりませんまたは役立つ MetaClass オブジェクト。

現在、子クラスの名前を次のように親のメインにハードコーディングすることで機能するようになりました。

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

私はそれからかなりカットしましたが、それは一般的な考えです. 交換したいです

"new HardCodedChildClassName()"

このクラスを拡張するすべてのクラスで機能するものを使用します。

上記の 2 つのコード スニップを考えると、コマンドは次のようにコマンド ラインから実行されます。

groovy HardCodedChildClassName dir

すべての @Command メソッドを静的にしたくないのですが、必要に応じて静的にすることもできますが、現在のところ、それを機能させることができるとは確信していません。

4

1 に答える 1

3

それが可能かどうかはわかりません。いずれにせよ、もしそうなら、それは醜いハックである可能性が高いです。main()この代替案をお勧めします。静的エントリポイントを使用するのではなく、を作成QuickCliRunnableます。Groovyは自動的にインスタンスを作成し、run()起動時にそれを呼び出します。

ここでの小さな問題の1つは、コマンドライン引数のキャプチャです。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()    
    }
}
于 2012-06-04T22:24:39.350 に答える