Anirudh Jayakumar
Anirudh Jayakumar

Reputation: 1234

How does Fernflower (decompiler in Intellij) manage to get parameter names when it is not available through reflection?

While trying to parse parameters of a funciton uisng java reflection APIs (m.getParameters()), the argument name is always hidden and instead we get names like arg0, arg1..

But when going through the decompile class in Intellij, the parameter names are clearly available and match the original source code.

How is this possible if the argument names are not in the bytecode?

Upvotes: 0

Views: 1833

Answers (1)

kaqqao
kaqqao

Reputation: 15459

Argument names are optionally stored in the bytecode, depending on the compiler options used.

From Java 8, you can pass the -parameters option to javac to preserve the names. If compiled that way, method.getParameters()[0].getName() will give you the original name.

Before Java 8, it was possible to preserve debug symbols by passing the -g parameter. But extracting them was a pain... you needed ASM to parse the bytecode to extract the info. Paranamer lib makes it simple though.

The classes you're decompiling have probably been compiled with the names preserved.

To compile your own classes that way, add -parameters to the compiler under:

Settings | Build, Execution, Deployment | Compiler | Java Compiler | Additional command line parameters in IntelliJ IDEA

or: Window | Preferences | Java | Compiler | Store information about method parameters (usable via reflection) in Eclipse.

There's also the <parameters> option in Maven's compiler plugin.

Upvotes: 1

Related Questions