i'm using ASM to build class file base on another Interface
, i could use java reflection to get methods of the Interface
, but i need to get the signature of it .
i found it's a private field , and there's no direct method to get it . is there any way out ? i use jdk7 . tks advance .
If all you want is the signature
field of java.lang.reflect.Method
, that's simple:
java.lang.reflect.Field f = java.lang.reflect.Method.class.getDeclaredField("signature");
f.setAccessible(true);
String sigature = f.get(yourMethod);
Where yourMethod
is a Method object.
Keep in mind: The signature field simply denotes the signature of a generic method, so attempting to get the signature of a non-generic method will simply return null
.
For example, let's assess the following method:
public static <T> void test(Class<T> c){}
This will return a signature of <T:Ljava/lang/Object;>(Ljava/lang/Class<TT;>;)V
This shows that the method declares one generic type
that must at least inherit java.lang.Object
and takes a class of that type as a parameter.
But, say we were to remove the generic from the method:
public static void test(Class c){}
This would result in the signature
field being null
.
Edit:
If you want to get the signature of any method (generic or not), there are a couple of ways to do it, but I find the following to be the most concise (although possibly clunky):
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();
}
Replacing '.' with '/' makes Gabriel Tofvesson's answer complete:
... .toString().replace('.', '/');
Otherwise, the signature returned would be something like ()Ljava.lang.Object;
. However, in signatures, the package names must be separated using slashes instead of periods: ()Ljava/lang/Object;
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With