skip to content

What does the -parameters compiler flag do, and which frameworks rely on it?

level: middleimportance: should knowfreq 45%

answer

  1. keeps real param names, not arg0
  2. MethodParameters bytecode attribute
  3. Spring @RequestParam/@PathVariable
  4. Boot parent enables it
  5. 'parameter name information not available' error

basics

~10 s

-parameters tells javac to keep real method parameter names in the bytecode. Without it, names become arg0, arg1. Frameworks like Spring MVC and JPA queries use them via reflection.

solid answer

~40 s

By default javac discards method parameter names from compiled bytecode (you get arg0, arg1 via reflection). The `-parameters` flag retains them in the class file's MethodParameters attribute. You enable it in the compiler plugin with `<parameters>true</parameter>` (or `<compilerArgs><arg>-parameters</arg></compilerArgs>`). Frameworks that read parameter names by reflection need it: Spring MVC binding `@PathVariable`/`@RequestParam` without an explicit value, Spring Data query derivation, JPA/Hibernate constructor binding, Jackson parameter-name module for records/immutables, and Spring's general DI in some cases. Modern Spring Boot enables it by default in its parent POM. Symptom of forgetting it: 'Name for argument of type [...] not specified, and parameter name information not available' or binding to arg0.

code

xml · 7 lines
xml
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <parameters>true</parameters>
  </configuration>
</plugin>

go deeper

for a junior

Knows -parameters keeps method parameter names so frameworks can read them.

for a middle

Can enable <parameters>true</parameters> and explains the arg0 fallback and Spring binding need.

for a senior

Recognizes the exact Spring error, knows Boot parent enables it, and distinguishes it from -g.

for a principal

Standardizes -parameters in the org parent POM so all services bind reliably regardless of framework defaults.

## The problem Java bytecode normally does NOT store the **names** you gave method parameters — only their types. At runtime `Method.getParameters()[0].getName()` returns synthetic `arg0`, `arg1`, etc. Many frameworks want the real names. ## What -parameters does The javac `-parameters` flag writes a `MethodParameters` attribute into each method, preserving the **actual parameter names**. Then reflection returns `userId` instead of `arg0`. ## Who needs it - **Spring MVC**: `@RequestParam Long userId` or `@PathVariable Long id` *without* an explicit value relies on the parameter name to know which request value to bind. - **Spring Data JPA**: deriving query parameters and `@Query` named-ish binding in some setups. - **Constructor/record binding**: Jackson's `ParameterNamesModule`, Spring's `@ConfigurationProperties` constructor binding, JPA constructor expressions. - **Any DI/mapping that matches by name** rather than by index or annotation value. ## Enabling it ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <parameters>true</parameters> </configuration> </plugin> ``` Equivalent low-level form: ```xml <configuration> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> ``` **Spring Boot's parent POM already sets `<parameters>true</parameters>`**, so Boot apps usually get it for free. ## Symptom of omission A classic Spring error: `Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.` Or values silently bind to the wrong field because Spring fell back to index/`arg0`. ## Cost Negligible — a small increase in class-file size; no runtime performance impact.

  • What happens to parameter names without -parameters?
    They are not stored in bytecode; reflection returns synthetic names like arg0, arg1, breaking name-based binding.
  • Why do Spring Boot apps often work without explicitly adding it?
    spring-boot-starter-parent already configures <parameters>true</parameters> on the compiler plugin.

saying these in an interview costs you the question

  • Claiming parameter names are always in bytecode — they are discarded by default.
  • Confusing -parameters with -g (debug/local-variable table) which also stores names but only for debugging, not reflection.
  • Thinking it has a runtime performance cost.

context