正在寻找 Java 能够识别调用它的方法的方法
Looking for Java method capable of identifying which method it is called by
我一直在为我的 Java 项目开发一个小型 logging/debug 库。我知道已经有很多好的,但我想自己做一个来学习。
作为这个库的一部分,我想拥有的一种方法是能够随时找出你所在的方法,类似于 __func__ C++。大多数时候,只使用 StackTrace 来查找它会很好,因为您通常只需要方法的名称(and/or 声明 class),但我想能够获取方法作为 java.lang.reflect.Method
的实例
最简单的方法就是简单地做
Method currentMethod = new Object() {}.getClass().getEnclosingMethod();
这会工作得很好,但如果不在方法本身中创建 'new Object() {}',我想不出一种方法来做同样的事情。理想情况下,我更愿意做一个简单的
Method currentMethod = _method();
得到相同的结果,但使用我目前的方法,它只会让我得到 _method 本身的方法实例。
是否有任何已知的方法可以实现此目的?没有也没关系,但有一个就好了。
编辑: 我收到了很多建议,例如 this post,主要提供了为您提供方法名称的答案。可以使用它(以及以相同方式获得的 Class 信息)来查找方法,但前提是所讨论的 class 只有一个具有该名称的方法。同名不同参数的方法不能用this来识别!
这可以使用 StackWalker
来完成(自 Java 9)。它不直接
提供 Method
但足以创建一个的信息。
这里的基本思想,可以改进(例如更好的异常):
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.Method;
public class MethodFinder {
public static Method method() {
return StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).walk(stream ->
stream
.filter(MethodFinder::notThisClass)
.findFirst()
.map(MethodFinder::frameToMethod))
.orElseThrow();
}
private static boolean notThisClass(StackFrame frame) {
return frame.getDeclaringClass() != MethodFinder.class;
}
private static Method frameToMethod(StackFrame frame) {
var cl = frame.getDeclaringClass();
try {
return cl.getDeclaredMethod(frame.getMethodName(), frame.getMethodType().parameterArray());
} catch (NoSuchMethodException | SecurityException ex) {
throw new RuntimeException(ex);
}
}
}
像Method myself = MethodFinder.method()
一样使用。
我一直在为我的 Java 项目开发一个小型 logging/debug 库。我知道已经有很多好的,但我想自己做一个来学习。
作为这个库的一部分,我想拥有的一种方法是能够随时找出你所在的方法,类似于 __func__ C++。大多数时候,只使用 StackTrace 来查找它会很好,因为您通常只需要方法的名称(and/or 声明 class),但我想能够获取方法作为 java.lang.reflect.Method
的实例最简单的方法就是简单地做
Method currentMethod = new Object() {}.getClass().getEnclosingMethod();
这会工作得很好,但如果不在方法本身中创建 'new Object() {}',我想不出一种方法来做同样的事情。理想情况下,我更愿意做一个简单的
Method currentMethod = _method();
得到相同的结果,但使用我目前的方法,它只会让我得到 _method 本身的方法实例。
是否有任何已知的方法可以实现此目的?没有也没关系,但有一个就好了。
编辑: 我收到了很多建议,例如 this post,主要提供了为您提供方法名称的答案。可以使用它(以及以相同方式获得的 Class 信息)来查找方法,但前提是所讨论的 class 只有一个具有该名称的方法。同名不同参数的方法不能用this来识别!
这可以使用 StackWalker
来完成(自 Java 9)。它不直接
提供 Method
但足以创建一个的信息。
这里的基本思想,可以改进(例如更好的异常):
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.Method;
public class MethodFinder {
public static Method method() {
return StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).walk(stream ->
stream
.filter(MethodFinder::notThisClass)
.findFirst()
.map(MethodFinder::frameToMethod))
.orElseThrow();
}
private static boolean notThisClass(StackFrame frame) {
return frame.getDeclaringClass() != MethodFinder.class;
}
private static Method frameToMethod(StackFrame frame) {
var cl = frame.getDeclaringClass();
try {
return cl.getDeclaredMethod(frame.getMethodName(), frame.getMethodType().parameterArray());
} catch (NoSuchMethodException | SecurityException ex) {
throw new RuntimeException(ex);
}
}
}
像Method myself = MethodFinder.method()
一样使用。