动态获取当前行号

动态获取当前行号

问题描述:

Java中是否有办法通过反射或一些非常棒的API动态获取当前行号?就像异常发生时一样,行号在堆栈跟踪中打印出来,如下所示:

Is there a way in Java to dynamically get the current line number through reflection or some awesome API? Just like when exceptions occur, the line number gets printed out in the stack trace like this:

at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:348)

现在有办法打印或登录以下代码?

Now is there a way to print or log like in the below code?

log.error("Error in: " + this.getClass.getName() + "at line #"+ this.getClass.getActualLine());

您可能会问,为什么我不打印行号?好吧,因为代码可能会在特定的log.error()方法调用之前被删除或添加。

You may ask, why don't I simply print the line number? Well because the code may get deleted or added before the specific log.error() method call.

我能够使用Thread.currentThread()。getStackTrace()方法创建一组函数,它们一起工作以产生调用第一个方法的代码的行号,如下所示:

I was able to use the Thread.currentThread().getStackTrace() method to create a set of functions that work together to produce the line number of the code that called the first method, like so:

/** @return The line number of the code that ran this method
 * @author Brian_Entei */
public static int getLineNumber() {
    return ___8drrd3148796d_Xaf();
}

/** This methods name is ridiculous on purpose to prevent any other method
 * names in the stack trace from potentially matching this one.
 * 
 * @return The line number of the code that called the method that called
 *         this method(Should only be called by getLineNumber()).
 * @author Brian_Entei */
private static int ___8drrd3148796d_Xaf() {
    boolean thisOne = false;
    int thisOneCountDown = 1;
    StackTraceElement[] elements = Thread.currentThread().getStackTrace();
    for(StackTraceElement element : elements) {
        String methodName = element.getMethodName();
        int lineNum = element.getLineNumber();
        if(thisOne && (thisOneCountDown == 0)) {
            return lineNum;
        } else if(thisOne) {
            thisOneCountDown--;
        }
        if(methodName.equals("___8drrd3148796d_Xaf")) {
            thisOne = true;
        }
    }
    return -1;
}

希望这会有所帮助!我将它们放在一个实用程序类中,以便它们不受影响,但仍然可以轻松访问。第二种方法是私有的,以防止除第一种方法之外的任何其他方法调用它,以便它始终正常工作。

Hope this helps! I put these in a utility class so that they are out of the way, but still easily accessible. The second method is private to prevent any other method other than the first method from calling it so that it always works correctly.