如何获取Java中的调用方类

我想获取方法的调用者类,即


class foo{


  bar();


}

在方法栏中,我需要获取类名称foo,然后找到了该方法:


Class clazz = sun.reflect.Reflection.getCallerClass(1);

但是,即使getCallerClass是public,当我尝试调用它时,Eclipse 也会说:


访问限制:由于必需的库C:\ Program Files \ Java \ jre7 \ lib \ rt.jar的限制,无法访问类型为Reflection的方法getCallerClass()


还有其他选择吗?


aluckdog
浏览 295回答 3
3回答

慕工程0101907

您可以生成堆栈跟踪并使用StackTraceElements中的信息。例如,实用程序类可以为您返回调用类名称:public class KDebug {&nbsp; &nbsp; public static String getCallerClassName() {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; StackTraceElement[] stElements = Thread.currentThread().getStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; for (int i=1; i<stElements.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackTraceElement ste = stElements[i];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!ste.getClassName().equals(KDebug.class.getName()) && ste.getClassName().indexOf("java.lang.Thread")!=0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ste.getClassName();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp;}}如果你调用KDebug.getCallerClassName()从bar(),你会得到"foo"。现在假设您想知道方法调用的类bar(这会更有趣,也许您真正想要的是)。您可以使用以下方法:public static String getCallerCallerClassName() {&nbsp;&nbsp; &nbsp; StackTraceElement[] stElements = Thread.currentThread().getStackTrace();&nbsp; &nbsp; String callerClassName = null;&nbsp; &nbsp; for (int i=1; i<stElements.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; StackTraceElement ste = stElements[i];&nbsp; &nbsp; &nbsp; &nbsp; if (!ste.getClassName().equals(KDebug.class.getName())&& ste.getClassName().indexOf("java.lang.Thread")!=0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (callerClassName==null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callerClassName = ste.getClassName();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if (!callerClassName.equals(ste.getClassName())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ste.getClassName();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return null;&nbsp;}那是用于调试吗?如果没有,可能有一个更好的解决方案。

神不在的星期二

要获得呼叫者/被呼叫者的类名,请使用以下代码,它对我来说很好用。String callerClassName = new Exception().getStackTrace()[1].getClassName();String calleeClassName = new Exception().getStackTrace()[0].getClassName();

繁花如伊

堆栈跟踪这高度取决于您要查找的内容...但是,这应该直接在此对象中获得调用此方法的类和方法。索引0 =线程索引1 =这个索引2 =直接呼叫者,可以是自己。索引3 ... n =相互调用以获得索引2及以下的类和方法。对于类/方法/文件名:Thread.currentThread().getStackTrace()[2].getClassName();Thread.currentThread().getStackTrace()[2].getMethodName();Thread.currentThread().getStackTrace()[2].getFileName();上课:Class.forName(Thread.currentThread().getStackTrace()[2].getClassName())仅供参考:Class.forName()抛出不是运行时的ClassNotFoundException。您需要尝试抓住。同样,如果您希望忽略类本身内的调用,则必须添加一些带有逻辑的循环来检查该特定事物。像...(我没有测试过这段代码,所以要当心)StackTraceElement[] stes = Thread.currentThread().getStackTrace();for(int i=2;i<stes.length;i++)&nbsp; if(!stes[i].getClassName().equals(this.getClass().getName()))&nbsp; &nbsp; return stes[i].getClassName();StackWalkerStackWalker StackFrame请注意,这不是详尽的指南,而是这种可能性的一个示例。打印每个StackFrame的Class(通过获取Class引用)StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE)&nbsp; &nbsp; .forEach(frame -> System.out.println(frame.getDeclaringClass()));做同样的事情,但首先将流收集到一个列表中。仅用于演示目的。StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE)&nbsp; &nbsp; .walk(stream -> stream.collect(Collectors.toList()))&nbsp; &nbsp; .forEach(frame -> System.out.println(frame.getDeclaringClass()));
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java