Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I print the method body reflectively?

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?

like image 753
unj2 Avatar asked May 31 '10 22:05

unj2


People also ask

How do you call a method in a string?

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.

How do you call a method from a method in Java?

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.

How do you make an object reflection?

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.


3 Answers

Java doesn't have that information at runtime. The only thing you could print would be bytecode.

like image 42
Chris Lercher Avatar answered Oct 24 '22 00:10

Chris Lercher


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.

like image 190
Stephen C Avatar answered Oct 23 '22 23:10

Stephen C


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).

like image 2
Yishai Avatar answered Oct 24 '22 01:10

Yishai