19

Javaでは、現在のメソッド(StackTraceを取得するメソッド)を呼び出したクラスとメソッドを取得することができます。

私の質問は、このメソッドを呼び出したメソッドに渡された引数を取得できますか?

デバッグのためにこれが必要です。

例えば:

baseClass {
   initialFunc(input) {
       var modifiedInput = input + " I modified you";
       otherClass.doSomething(modifiedInput);
   }
}

otherClass {
    doSomething(input)  {
         //GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
    }
}

スタックトレースからこの情報を取得できますか、それとも他の手段がありますか?

(実行時にこれを実行できる必要があり、baseClassのソースを実際に変更できないことに注意してください。これは、ソースを事前に知らないデバッグクラスの機能になります)

ありがとう。

4

6 に答える 6

4

これが標準のJavaAPIを使用して可能であるとは思いません。

あなたができることは、AspectJを使用し、呼び出し元のメソッドにポイントカットを配置し、引数を保存し、呼び出されたメソッドにポイントカットを配置し、引数を渡すことです。

もう1つのオプション(少し高度な)は、元の引数を保存し、それらを追加の引数として次のメソッドに渡すカスタムのバイトコード書き換えクラスローダーを使用することです。これを実装するには、おそらく1〜2日かかります。適切なフレームワークはBCELまたはASMです。

于 2011-02-09T10:36:23.317 に答える
2

範囲外ですが、ガベージコレクションにまだアクセスできないため、これは可能だと思いますinput。そのため、値はまだ存在しますが、残念ながら、デフォルトのAPIでアクセスする方法はないと思います。これは、ロギングアプローチ用にカスタム実装されたNDC(ネストされた診断コンテキスト)で可能になる可能性があります。

于 2011-02-09T10:35:56.287 に答える
0

なぜJavaでこれをやりたいのかわかりませんか?

私が考えることができる唯一の方法は、渡された文字列のカスタムラッパーオブジェクトを作成することです。これにより、毎回新しい文字列ではなく、ラッパーへの参照が送信されます。
ただし、元のコードが乱雑になり、エラーが発生しやすくなるため、これには反対することをお勧めします。

この問題は、Eclipseに組み込まれているようなデバッガーを使用して、状態を検査することで解決できない可能性がありますか?

于 2011-02-09T10:45:39.903 に答える
0

私の場合、後で実行フロー内で使用するために、特定のスタックフレーム内のメソッドに渡されたパラメーター値を取得する必要がありました

以前ThreadLocalは保存していましたが、必要なときに、次のように宣言したコードの任意の時点で取得できました。public static

これがスケルトンの例です

public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);

methodWithImportantParam(SomeType importantValue){
    // save it in the static threadLocal Field
    this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
    // continue method logic
}

そして、その値が必要なコードのどこか

YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()

ただし、値を設定してから取得する実行フローを確認してください

私の答えがこの質問に価値のあるものを追加することを願っています

于 2020-02-26T13:09:19.107 に答える
-2

呼び出し元のメソッドとそのクラスの名前を取得できますが、現在のメソッドにコードを追加する必要があります。

    public static void main(String[] args) throws Exception {
    call();
}

private static void call() {
    Exception exception = new Exception();
    for(StackTraceElement trace : exception.getStackTrace()){
        System.out.println(trace.getMethodName());
    }
}

これにより、メソッド名「call」と「main」が呼び出された順序(逆)で出力されます。

于 2013-08-01T11:17:20.603 に答える
-4

これはReflectionAPIを使用して可能です!

public class StackTrace {
    public static void main(String args[]) {
        StackTrace st = new StackTrace();
        st.func();
    }
    public void func() {
        OtherClass os =new OtherClass();
        os.getStackTrace(this);
    }
}

class OtherClass {
    void getStackTrace(Object obj)  {
        System.out.println(obj.getClass());
    }
}
于 2011-02-09T10:44:20.590 に答える