我想得到方法的调用者类,即
class foo{
bar();
}
Run Code Online (Sandbox Code Playgroud)
在方法栏中,我需要获取类名foo,我找到了这个方法:
Class clazz = sun.reflect.Reflection.getCallerClass(1);
Run Code Online (Sandbox Code Playgroud)
但是,即使getCallerClass是public,当我试着调用它时,Eclipse说:
访问限制:由于对所需库C:\ Program Files\Java\jre7\lib\rt.jar的限制,无法访问Reflection类型的方法getCallerClass()
还有其他选择吗?
Den*_*ret 92
您可以生成堆栈跟踪并使用StackTraceElements中的信息.
例如,实用程序类可以返回调用类名:
public class KDebug {
public static String getCallerClassName() {
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
for (int i=1; i<stElements.length; i++) {
StackTraceElement ste = stElements[i];
if (!ste.getClassName().equals(KDebug.class.getName()) && ste.getClassName().indexOf("java.lang.Thread")!=0) {
return ste.getClassName();
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如果你调用KDebug.getCallerClassName()从bar(),你会得到"foo".
现在假设你想知道调用方法的类bar(这更有趣,也许你真正想要的).你可以使用这个方法:
public static String getCallerCallerClassName() {
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
String callerClassName = null;
for (int i=1; i<stElements.length; i++) {
StackTraceElement ste = stElements[i];
if (!ste.getClassName().equals(KDebug.class.getName())&& ste.getClassName().indexOf("java.lang.Thread")!=0) {
if (callerClassName==null) {
callerClassName = ste.getClassName();
} else if (!callerClassName.equals(ste.getClassName())) {
return ste.getClassName();
}
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
这是调试吗?如果没有,可能会有更好的解决方案来解决您的问题.
Hit*_*its 32
要获得调用者/被调用者类名称使用下面的代码,它对我来说很好.
String callerClassName = new Exception().getStackTrace()[1].getClassName();
String calleeClassName = new Exception().getStackTrace()[0].getClassName();
Run Code Online (Sandbox Code Playgroud)
Ats*_*lgs 28
这高度取决于你正在寻找的......但是这应该得到直接在这个对象中调用这个方法的类和方法.
对于类/方法/文件名:
Thread.currentThread().getStackTrace()[2].getClassName();
Thread.currentThread().getStackTrace()[2].getMethodName();
Thread.currentThread().getStackTrace()[2].getFileName();
Run Code Online (Sandbox Code Playgroud)
上课:
Class.forName(Thread.currentThread().getStackTrace()[2].getClassName())
Run Code Online (Sandbox Code Playgroud)
FYI:Class.forName()抛出一个非运行时的ClassNotFoundException.你需要尝试捕获.
此外,如果您要忽略类本身内的调用,则必须添加一些带逻辑的循环来检查该特定内容.
像...这样的东西(我没有测试过这段代码所以要小心)
StackTraceElement[] stes = Thread.currentThread().getStackTrace();
for(int i=2;i<stes.length;i++)
if(!stes[i].getClassName().equals(this.getClass().getName()))
return stes[i].getClassName();
Run Code Online (Sandbox Code Playgroud)
只是一个想法....
Lun*_*una 12
SecurityManager有一个受保护的方法getClassContext
通过创建扩展SecurityManager的实用程序类,您可以访问它.
public class CallingClass extends SecurityManager {
public static final CallingClass INSTANCE = new CallingClass();
public Class[] getCallingClasses() {
return getClassContext();
}
}
Run Code Online (Sandbox Code Playgroud)
使用CallingClass.INSTANCE.getCallingClasses()检索调用类.
还有一个小型图书馆(免责声明:我的)WhoCalled公开了这些信息.它在可用时使用Reflection.getCallerClass,否则回退到SecurityManager.
我知道这是一个古老的问题,但我相信提问者想要上课,而不是课堂名称.我写了一个小方法来获得实际的课程.它有点像学习,可能并不总是有效,但有时当你需要实际的课时,你将不得不使用这种方法......
/**
* Get the caller class.
* @param level The level of the caller class.
* For example: If you are calling this class inside a method and you want to get the caller class of that method,
* you would use level 2. If you want the caller of that class, you would use level 3.
*
* Usually level 2 is the one you want.
* @return The caller class.
* @throws ClassNotFoundException We failed to find the caller class.
*/
public static Class getCallerClass(int level) throws ClassNotFoundException {
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
String rawFQN = stElements[level+1].toString().split("\\(")[0];
return Class.forName(rawFQN.substring(0, rawFQN.lastIndexOf('.')));
}
Run Code Online (Sandbox Code Playgroud)