如何获取java反射Method对象的“signature”字段

Ada*_*s.H 4 java reflection

我正在使用 ASM 在另一个基础上构建类文件Interface,我可以使用 java 反射来获取该类的方法Interface,但我需要获取它的签名。 在此输入图像描述

我发现它是一个私有字段,并且没有直接的方法来获取它。有什么出路吗?我用jdk7。谢谢提前。

Gab*_*son 5

如果您想要的只是signature的字段java.lang.reflect.Method,那很简单:

java.lang.reflect.Field f = java.lang.reflect.Method.class.getDeclaredField("signature");
f.setAccessible(true);
String sigature = f.get(yourMethod);
Run Code Online (Sandbox Code Playgroud)

其中yourMethod是 Method 对象。

请记住:签名字段仅表示泛型方法的签名,因此尝试获取非泛型方法的签名将仅返回null。

例如,让我们评估以下方法:

public static <T> void test(Class<T> c){}
Run Code Online (Sandbox Code Playgroud)

这将返回一个签名<T:Ljava/lang/Object;>(Ljava/lang/Class<TT;>;)V

这表明该方法声明了一种至少必须继承的泛型类型java.lang.Object,并采用该类型的类作为参数。

但是,假设我们要从方法中删除泛型:

public static void test(Class c){}
Run Code Online (Sandbox Code Playgroud)

这将导致该signature字段为null。

编辑:

如果您想获得任何方法(通用或非通用)的签名,有几种方法可以做到这一点,但我发现以下是最简洁的(尽管可能很笨拙):

public static String getSignature(Method m){
    String sig;
    try {
        Field gSig = Method.class.getDeclaredField("signature");
        gSig.setAccessible(true);
        sig = (String) gSig.get(m);
        if(sig!=null) return sig;
    } catch (IllegalAccessException | NoSuchFieldException e) { 
        e.printStackTrace();
    }

    StringBuilder sb = new StringBuilder("(");
    for(Class<?> c : m.getParameterTypes()) 
        sb.append((sig=Array.newInstance(c, 0).toString())
            .substring(1, sig.indexOf('@')));
    return sb.append(')')
        .append(
            m.getReturnType()==void.class?"V":
            (sig=Array.newInstance(m.getReturnType(), 0).toString()).substring(1, sig.indexOf('@'))
        )
        .toString();
}
Run Code Online (Sandbox Code Playgroud)