java 获得调用者类名_如何在Java中获得调用者类

您可以生成堆栈跟踪并使用StackTraceElements中的信息。

例如,一个实用程序类可以返回您的调用类名称:

public class KDebug { public static String getCallerClassName() { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); for (int i=1; i

如果你从bar()调用KDebug.getCallerClassName() ,你会得到"foo" 。

现在假设你想知道方法调用bar的类(这更有趣,也许你真正想要的)。 你可以使用这个方法:

public static String getCallerCallerClassName() { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); String callerClassName = null; for (int i=1; i

这是为了debugging吗? 否则,可能会有更好的解决scheme来解决您的问题。

要获得调用者/被调用者类的名称使用下面的代码,它对我来说工作正常。

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())

FYI:Class.forName()抛出一个不是运行时的ClassNotFoundException。 你需要尝试抓住。

另外,如果你想忽略类中的调用,你必须添加一些逻辑循环来检查特定的事情。

就像…(我没有testing这段代码,所以要小心)

StackTraceElement[] stes = Thread.currentThread().getStackTrace(); for(int i=2;i

只是一个想法….

SecurityManager有一个受保护的方法getClassContext

通过创build扩展SecurityManager的实用程序类,您可以访问它。

public class CallingClass extends SecurityManager { public static final CallingClass INSTANCE = new CallingClass(); public Class[] getCallingClasses() { return getClassContext(); } }

使用CallingClass.INSTANCE.getCallingClasses()来检索调用类。

还有一个小图书馆(免责声明:我的) WhoCalled哪个公开这个信息。 它在可用时使用Reflection.getCallerClass,否则返回到SecurityManager。

我知道这是一个老问题,但我相信提问者想要的是class级,而不是class级名称。 我写了一个方法来获得实际的课程。 这是一种微妙的,可能并不总是工作,但有时当你需要实际的类,你将不得不使用这种方法…

/** * 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('.'))); }

这是获取调用者类最有效的方法。 其他方法需要整个堆栈转储,只给你类名。

但是,这个课程在sun.*下sun.*这是真正的内部使用。 这意味着它可能无法在其他Java平台或其他Java版本上运行。 你必须决定这是否是一个问题。

OP正在遇到的错误消息只是一个Eclipsefunction。 如果你愿意将你的代码绑定到特定的制造商(甚至是版本)的JVM,你可以有效地使用方法sun.reflect.Reflection.getCallerClass() 。 然后,您可以编译Eclipse之外的代码,或者将其configuration为不将此诊断视为错误。

最糟糕的Eclipseconfiguration是通过以下方式禁用所有发生的错误:

Project Properties / Java Compiler / Errors/Warnings / Enable project specific settings设置为选中/ Deprecated and restrited API / Forbidden reference (access rules)设置为Warning或Ignore 。

更好的Eclipseconfiguration是通过以下方式禁用特定的错误:

Project Properties / Java Build Path / Libraries / JRE System Library展开/ Access rules:select/ Edit... / Add... / Resolution:设置为Discouraged或Accessible / Rule Pattern设置为sun/reflect/Reflection 。

我正在使用以下方法从堆栈跟踪中获取特定类的调用方:

package test.log; public class CallerClassTest { public static void main(final String[] args) { final Caller caller = new Caller(new Callee()); caller.execute(); } private static class Caller { private final Callee c; public Caller(final Callee c) { this.c = c; } void execute() { c.call(); } } static class Callee { void call() { System.out.println(getCallerClassName(this.getClass())); } } /** * Searches the current threads stacktrace for the class that called the given class. Returns {@code null} if the * calling class could not be found. * * @param clazz * the class that has been called * * @return the caller that called the class or {@code null} */ public static String getCallerClassName(final Class> clazz) { final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String className = clazz.getName(); boolean classFound = false; for (int i = 1; i < stackTrace.length; i++) { final StackTraceElement element = stackTrace[i]; final String callerClassName = element.getClassName(); // check if class name is the requested class if (callerClassName.equals(className)) classFound = true; else if (classFound) return callerClassName; } return null; } }

由于我现在有同样的问题,这就是我所做的:

我更喜欢com.sun.Reflection而不是stackTrace,因为堆栈跟踪只产生名称而不是类(包括类加载器)本身。

该方法已被弃用,但仍在Java 8 SDK中。

//方法描述符#124(I)Ljava / lang / Class; (不赞成使用)//签名:(I)Ljava / lang / Class ; @ java.lang.Deprecated public static native java.lang.Class getCallerClass(int arg0);

没有int参数的方法不被弃用

//方法描述符#122()Ljava / lang / Class; //签名:()Ljava / lang / Class ; @ sun.reflect.CallerSensitive public static native java.lang.Class getCallerClass();

由于我必须是平台独立的,包括安全限制,所以我只是创build一个灵活的方法:

检查com.sun.Reflection是否可用(安全例外禁用此机制)

如果1是肯定的,那么用int或no int参数来获取方法。

如果2是,则调用它。

如果没有达到3.我使用堆栈跟踪返回名称。 我使用了一个特殊的结果对象,它包含了类或者string,这个对象告诉了它是什么以及为什么。

[摘要]我使用stacktrace进行备份,并绕过eclipse编译器警告我使用reflection。 工作非常好。 保持代码清洁,像一个魅力工作,也说明了正确涉及的问题。

我用了很长时间,今天我search了一个相关的问题

查找下面的一个简单的例子,说明如何获得类和方法名称。

public static void main(String args[]) { callMe(); } void callMe() { try { throw new Exception("Who called me?"); } catch( Exception e ) { System.out.println( "I was called by " + e.getStackTrace()[1].getClassName() + "." + e.getStackTrace()[1].getMethodName() + "()!" ); } }

e有getClassName() , getFileName() , getLineNumber()和getMethodName() …

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值