Right now I have
private static void getMethods(Class<? extends Object> clazz) {
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method aMethod : declaredMethods) {
aMethod.setAccessible(true);
// Print the declaration
System.out.print(Modifier.toString(aMethod.getModifiers()) + " "
+ aMethod.getReturnType().getSimpleName() + " " + aMethod.getName());
// Get Parameter Types
getParameters(aMethod);
//Empty Body
System.out.println("{}\n");
}
}
Which prints most information reflectively but creates an empty body. How do I add to the reflective nature of Java to print the method body?
There are two methods to call a function from string stored in a variable. The first one is by using the window object method and the second one is by using eval() method. The eval() method is older and it is deprecated.
To call a method in Java, simply write the method's name followed by two parentheses () and a semicolon(;). If the method has parameters in the declaration, those parameters are passed within the parentheses () but this time without their datatypes specified.
We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.
Java doesn't have that information at runtime. The only thing you could print would be bytecode.
How do I add to the reflective nature of Java to print the method body?
With considerable difficulty, I'm afraid.
For a start, the original source code is most likely to be unavailable to a running program. As a rule, developers do not include source code in the binary JARs. (And even if they do, there is not guarantee that they will be the "real" sources.)
You can usually obtain the bytecodes for the class by translating the FQN for the class into the bytecode file and using the classes classloader to load the file as a resource stream. But it is not guaranteed that the bytecodes you get this way will be the same as what were loaded. (Some classloaders mess around with the bytecodes for various reasons.)
Assuming that you can get the real bytecodes, the last step will be to either display them raw, or disassemble or decompile them to something more readable. You should be able to use javap
to do a disassembly, but decompilation would entail using a third party product. Of course, the decompiled code will look significantly different to the original code, and if the bytecodes have been obfuscated they source code will be pretty much unreadable.
The only way to do something like that is to write/use a decompiler. That involves reading the byte-code directly, which is not a standard function of the ReflectionAPI. The source code as represented in the original source file is gone, and it may not be possible to completely reproduce it as it was from byte code. (For example, Generics would be lost, as well as use of an enhanced for loop wouldn't be distinguishable and I'm sure there are others).
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