19

リフレクションやその他の魔法を使用してメソッドの行番号を取得することは可能ですか?
メソッドが現在の Stacktrace 内にある場合は可能です。を使用Thread.currentThread().getStackTrace()すると、 の行番号を取得できますStackTraceElementjava.lang.reflect.Methodしかし、オブジェクトしか取得できなかった場合はどうすればよいでしょうか?

クラスについてはこれを見つけました-> Java.lang.Classオブジェクトからソースファイル名/行番号を取得する方法ですが、メソッドには役立ちません。

4

3 に答える 3

18

私は同じことをしたかったので、いくつかの調査の後、javassist に落ち着きました。javassist を追加する必要があります (私はバージョン 3.15.0-GA を使用しました)。

次のクラスを指定して、「x」メソッドの場所を決定します。メソッド名「x」はハードコーディングされていますが、私と同じボートに乗っている場合、リフレクションは難しくないので、メソッド名のリストを取得できると確信しています。次のようにして行番号を取得できますメソッドの:

public class Widget {
    void x(){System.out.println("I'm x\n");}
    //comment added to create space
    void y(){System.out.println("I'm y\n");} 
}

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class App {
    public static void main(String[] args) throws NotFoundException {
        System.out.println("Get method line number with javassist\n");
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.quaternion.demo.Widget");
        CtMethod methodX = cc.getDeclaredMethod("x");
        int xlineNumber = methodX.getMethodInfo().getLineNumber(0);
        System.out.println("method x is on line " + xlineNumber + "\n");
    }
}

出力method x is on line 12私の場合は正確ですが、いくつかのコメントを切り取りました...

: コメントで Pete83 が述べたように、このメソッドは実際には、メソッドを宣言する行ではなく、メソッドのコードの最初の行を返します。ほとんどの場合、相対位置 (宣言された順序) を確立し、この情報を独自の規則に使用する必要があるため、これは通常問題にはなりません。これは、コード自体内の位置によって容易に決定できる序数値を注釈内に含める必要があると感じたときにいつでも発生します。


javassist のクイック リファレンス Maven 座標:

<dependency>
   <groupId>org.javassist</groupId> <!-- if a version prior to 3.13.0-GA is needed use "javassist" and not "org.javassist" -->
   <artifactId>javassist</artifactId>
   <version>3.15.0-GA</version>
</dependency>
于 2013-02-20T06:38:24.970 に答える
9

私にとって、Javassist を指している Quaternion の答えは、この質問に対する完璧な解決策です。それは私にとってはうまくいき、 java.lang.reflect.Method オブジェクトのみを取得するときにも使用できます。

これが私がやった方法です:

Method m; // the method object
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(m.getDeclaringClass().getCanonicalName());
CtMethod javassistMethod = cc.getDeclaredMethod(m.getName());
int linenumber = javassistMethod.getMethodInfo().getLineNumber(0);
于 2013-05-02T11:17:57.220 に答える
0

これがどのメソッドに適用されるかわからないため、メソッドから行番号を取得することはできません。メソッドは、選択したサブクラスの任意のサブクラスを呼び出すことができます。

于 2012-10-11T08:05:13.037 に答える