【问题标题】:get Name of enclosing Method获取封闭方法的名称
【发布时间】:2010-06-29 15:19:54
【问题描述】:

有方法

public void foo(){
  //..    
}

有没有办法在运行时获取 methodName(在本例中为 foo)?

我知道如何通过

获取类名

this.getClass().getName()

或通过以下方式获取所有公共方法 Method[] methods = this.getClass().getMethods(); 一旦我有了方法名称,参数也很重要,因为可能有多个方法具有相同的名称

【问题讨论】:

标签: java reflection


【解决方案1】:

我使用如下代码:

  /**
   * Proper use of this class is
   *     String testName = (new Util.MethodNameHelper(){}).getName();
   *  or
   *     Method me = (new Util.MethodNameHelper(){}).getMethod();
   * the anonymous class allows easy access to the method name of the enclosing scope.
   */
  public static class MethodNameHelper {
    public String getName() {
      final Method myMethod = this.getClass().getEnclosingMethod();
      if (null == myMethod) {
        // This happens when we are non-anonymously instantiated
        return this.getClass().getSimpleName() + ".unknown()"; // return a less useful string
      }
      final String className = myMethod.getDeclaringClass().getSimpleName();
      return className + "." + myMethod.getName() + "()";
    }

    public Method getMethod() {
      return this.getClass().getEnclosingMethod();
    }
}

去掉className + "."部分,看看它是否满足您的需求。

【讨论】:

    【解决方案2】:

    我不确定你为什么需要这样做,但你总是可以创建new Throwable()getStackTace(),然后查询StackTraceElement.getMethodName()

    作为奖励,您可以获得直到执行点的整个堆栈跟踪,而不仅仅是立即封闭的方法。

    相关问题

    【讨论】:

    • 谢谢!我正在创建 CommonBaseEvents 除了 className 之外还需要 MethodName 参见download.boulder.ibm.com/ibmdl/pub/software/dw/library/…
    • Jonathon 指出了 'getStackTace()' 的 JavaDoc 中所说的“某些虚拟机在某些情况下可能会从堆栈跟踪中省略一个或多个堆栈帧。”所以我正在尝试反思。你知道它是如何通过反射工作的吗?
    【解决方案3】:

    使用此代码:

    System.out.println(new Throwable().getStackTrace()[0].getMethodName());
    

    【讨论】:

      【解决方案4】:

      反思是一种方式。另一种缓慢且potentially unreliable 的方式是使用堆栈跟踪。

      StackTraceElement[] trace = new Exception().getStackTrace();
      String name = trace[0].getMethodName();
      

      同样的想法,但来自thread

      StackTraceElement[] trace = Thread.currentThread().getStackTrace();
      String name = trace[0].getMethodName();
      

      【讨论】:

      • 为什么不可靠?你有通过反射获得它的例子吗?
      • @Martin Dürrmeier - 反射更多。我添加了有关 getStackTrace 方法和潜在不可靠性信息的链接。
      • 感谢您的链接。你能告诉我如何通过反射来做到这一点吗?
      • @Martin Dürrmeier - 通常通过反射,您可以事先知道方法名称。使用Class 对象,您可以调用getMethods 并将名称与正确的参数类型匹配以获得Method 对象。查看Class 的JavaDoc:java.sun.com/javase/6/docs/api/java/lang/Class.html
      【解决方案5】:

      您可以对名称进行硬编码。

      // The Annotation Processor will complain if the two method names get out of synch
      class MyClass
      {
          @HardCodedMethodName ( ) 
           void myMethod ( )
           {
                @ HardCodedMethodName // Untried but it seems you should be able to produce an annotation processor that compile time enforces that myname = the method name.
                String myname = "myMethod" ;
                ...
           }
      }
      

      【讨论】:

        【解决方案6】:

        这个问题是几年前提出的,但我认为值得用一个更简单的表达式来综合以前的答案:

        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        

        尽管它的丑陋和引用的可靠性问题,它是干净的,可以很容易地与Log.x() 函数一起使用以帮助调试。

        【讨论】:

          猜你喜欢
          • 2012-03-21
          • 2023-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-12
          • 2011-10-09
          • 2011-11-25
          相关资源
          最近更新 更多