How do I find the caller of a method using stacktrace or reflection?

后端 未结 12 1184
鱼传尺愫
鱼传尺愫 2020-11-21 13:26

I need to find the caller of a method. Is it possible using stacktrace or reflection?

12条回答
  •  忘掉有多难
    2020-11-21 13:56

         /**
           * Get the method name for a depth in call stack. 
    * Utility function * @param depth depth in the call stack (0 means current method, 1 means call method, ...) * @return method name */ public static String getMethodName(final int depth) { final StackTraceElement[] ste = new Throwable().getStackTrace(); //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName()); return ste[ste.length - depth].getMethodName(); }

    For example, if you try to get the calling method line for debug purpose, you need to get past the Utility class in which you code those static methods:
    (old java1.4 code, just to illustrate a potential StackTraceElement usage)

            /**
              * Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils". 
    * From the Stack Trace. * @return "[class#method(line)]: " (never empty, first class past StackTraceUtils) */ public static String getClassMethodLine() { return getClassMethodLine(null); } /** * Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass.
    * Allows to get past a certain class. * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. * @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils) */ public static String getClassMethodLine(final Class aclass) { final StackTraceElement st = getCallingStackTraceElement(aclass); final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber() +")] <" + Thread.currentThread().getName() + ">: "; return amsg; } /** * Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass.
    * Stored in array of the callstack.
    * Allows to get past a certain class. * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. * @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils) * @throws AssertionFailedException if resulting statckTrace is null (RuntimeException) */ public static StackTraceElement getCallingStackTraceElement(final Class aclass) { final Throwable t = new Throwable(); final StackTraceElement[] ste = t.getStackTrace(); int index = 1; final int limit = ste.length; StackTraceElement st = ste[index]; String className = st.getClassName(); boolean aclassfound = false; if(aclass == null) { aclassfound = true; } StackTraceElement resst = null; while(index < limit) { if(shouldExamine(className, aclass) == true) { if(resst == null) { resst = st; } if(aclassfound == true) { final StackTraceElement ast = onClassfound(aclass, className, st); if(ast != null) { resst = ast; break; } } else { if(aclass != null && aclass.getName().equals(className) == true) { aclassfound = true; } } } index = index + 1; st = ste[index]; className = st.getClassName(); } if(resst == null) { //Assert.isNotNull(resst, "stack trace should null"); //NO OTHERWISE circular dependencies throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$ } return resst; } static private boolean shouldExamine(String className, Class aclass) { final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith("LogUtils" ) == false || (aclass !=null && aclass.getName().endsWith("LogUtils"))); return res; } static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st) { StackTraceElement resst = null; if(aclass != null && aclass.getName().equals(className) == false) { resst = st; } if(aclass == null) { resst = st; } return resst; }

提交回复
热议问题