簡體   English   中英

如何在Java中獲取方法的字符串名稱?

[英]How to get string name of a method in java?

如何通過反射找出方法的字符串名稱是什么?

例如給出:

class Car{
   public void getFoo(){
   }
}

我想獲取字符串“ getFoo”,如下所示:

 Car.getFoo.toString() == "getFoo" // TRUE

您可以像這樣獲取字符串:

Car.class.getDeclaredMethods()[0].getName();

這是類中單個方法的情況。 如果要遍歷所有聲明的方法,則必須遍歷Car.class.getDeclaredMethods()返回的數組:

for (Method method : Car.class.getDeclaredMethods()) {
    String name = method.getName();
}

如果要查看所有視圖,則應使用getDeclaredMethods()getMethods()將僅返回公共方法。

最后,如果您想查看當前正在執行的方法的名稱,則應使用以下代碼:

Thread.currentThread().getStackTrace()[1].getMethodName();

這將獲取當前線程的堆棧跟蹤,並在其頂部返回該方法的名稱。

由於方法本身不是對象,因此它們沒有直接的屬性(就像您希望使用JavaScript之類的一流函數那樣)。

最接近的方法是調用Car.class.getMethods()

Car.class是一個Class對象,可用於調用任何反射方法。

但是,據我所知,一種方法無法識別自己。

那么,您想獲取當前正在執行的方法的名稱嗎? 這是一種難看的方法:

Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();

嘗試這個,

 import java.lang.reflect.*;
    public class DumpMethods {
        public static void main(String args[]) {
            try {
                Class c = Class.forName(args[0]);
                Method m[] = c.getDeclaredMethods();
                for (int i = 0; i < m.length; i++)
                    System.out.println(m[i].toString());
            } catch (Throwable e) {
                System.err.println(e);
            }
        }
    }

查看此線程:

獲取當前執行方法的名稱

它提供了更多解決方案-例如:

String name = new Object(){}.getClass().getEnclosingMethod().getName();

使用Java 8,您可以用幾行代碼(幾乎)執行此操作,而無需任何其他庫。 關鍵是將您的方法轉換為可序列化的lambda表達式。 因此,您可以定義一個簡單的接口,如下所示:

@FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
  // Combined interface for Function and Serializable
}

現在,我們需要將lambda表達式轉換為SerializedLambda對象。 顯然,Oracle確實不希望我們這樣做,因此請一籌莫展...由於所需的方法是私有的,因此我們需要使用反射來調用它:

private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
  Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
  findMethod.setAccessible(true);

  SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
  return invokeMethod.getImplMethodName();
}

為了簡單起見,我在這里使用Springs ReflectionUtils類,但是您當然可以通過手動循環所有超類並使用getDeclaredMethod查找writeReplace方法來替換它。

就是這樣,現在您可以像這樣使用它:

@Test
public void testNameOf() throws Throwable {
  assertEquals("getName", nameOf(MyClassTest::getName));
}

我尚未在Java 9s模塊系統中進行過檢查,因此免責聲明,使用更新的Java版本執行此操作可能會比較棘手...

等等,因為您已經知道方法名稱,難道不能只將其鍵入為字符串嗎?

代替(偽) Class.methodName.toString() ,只需使用"methodName ”即可。

否則,您可以使用Class#getDeclaredMethods()獲取類中的所有方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM