如何获取方法的行号?

是否可以使用reflection或其他魔法获取方法的行号?
如果方法在当前Stacktrace内,则可能。 使用Thread.currentThread().getStackTrace() ,可以获得StackTraceElement的行号。 但是如果我只获得了java.lang.reflect.Method对象,我该怎么办?

我发现这个,对于classes-> 如何从java.lang.Class对象获取源文件名/行号,但它对方法没有用。

我想做同样的事情,经过一些研究确定了javassist。 您需要添加javassist(我使用的是3.15.0-GA版本)。

鉴于以下类确定“x”方法的位置。 方法名称“x”是硬编码的,但如果你和我在同一条船上,reflection并不难,所以我相信你可以得到一个方法名称列表,然后以下内容将让你获得行号方法:

 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坐标:

  org.javassist  javassist 3.15.0-GA  

对我来说,Quaternion指向Javassist的答案是这个问题的完美解决方案。 它适用于我,当你只获得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); 

您无法从Method获取行号,因为您不知道这适用于哪种方法。 方法可以调用您选择的子类。