java 如何获取方法的行号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12834887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the line number of a method?
提问by Chriss
Is it possible to get the line number of an method using reflection or other magic?
It is possible if the method is inside the current Stacktrace. Using Thread.currentThread().getStackTrace()
, one can get the line number of an StackTraceElement
. But what can I do if I only got the java.lang.reflect.Method
Object?
是否可以使用反射或其他魔法获取方法的行号?
如果该方法在当前 Stacktrace 中,则是可能的。使用Thread.currentThread().getStackTrace()
,可以得到一个StackTraceElement
. 但是如果我只拿到了java.lang.reflect.Method
Object 怎么办?
I found this, for classes-> How to get source file-name/line-number from a java.lang.Class objectbut it's not useful for methods.
我发现这个,对于类->如何从 java.lang.Class 对象获取源文件名/行号,但它对方法没有用。
回答by Quaternion
I wanted to do the same thing and after some research settled on javassist. You will need to add javassist (I used version 3.15.0-GA).
我想做同样的事情,经过一些研究后,我选择了 javassist。您将需要添加 javassist(我使用的是 3.15.0-GA 版)。
Given the following class determine the location of the "x" method. The method name "x" is hard coded however if you are in the same boat as me, the reflection isn't hard so I'm confident you can get a list of method names, then the following will let you get the line numbers of the methods:
给定以下类,确定“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");
}
}
Output: method x is on line 12
which in my case is accurate I cut out some comments...
输出:method x is on line 12
在我的情况下是准确的,我删掉了一些评论......
Note: As mentioned by Pete83 in the comments, this method actually returns the first line of code in the method and not the line which declares the method. This usually won't be an issue as most will probably want to establish relative position (the order in which they were declared) and use this information for your own conventions. This would come up any time you felt the need to include an ordinal value within an annotation which could be readily determined by the position within the code itself.
注意:正如 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>
回答by Thorben
For me the answer of Quaternion pointing to Javassist is the perfect solution to this question. It works for me and you can use it also when you only get the java.lang.reflect.Method object.
对我来说,Quaternion 指向 Javassist 的答案是这个问题的完美解决方案。它对我有用,当你只获得 java.lang.reflect.Method 对象时,你也可以使用它。
This is how I did it:
我是这样做的:
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);
回答by Peter Lawrey
You can't get a line number from a Method because you don't know what method this applies to. A method can call any sub-class of the the one you chose.
您无法从方法中获取行号,因为您不知道这适用于什么方法。一个方法可以调用您选择的方法的任何子类。