Why Java’s Anonymous Inner Classes Require Final Variables (And How Kotlin Differs)
The article explains why Java’s anonymous inner classes enforce final or effectively‑final variables, shows how the compiler treats these classes, contrasts this behavior with Kotlin’s ability to modify primitive values inside anonymous classes, and illustrates the differences with decompiled bytecode examples.
Phenomenon Description
Before Java 8, using an external variable inside an anonymous inner class caused a compilation error: “Cannot refer to a non‑final variable arg inside an inner class defined in a different method”.
After Java 8, the same code no longer shows that error, but attempting to modify the variable still results in a warning such as “Variable 'num' is accessed from within inner class, need to be final or effectively final”.
Kotlin, by contrast, does not impose this restriction.
Reason Analysis
Compiling the code with javac generates several .class files. The TestInnerClass$1.class file represents the compiled anonymous inner class. Decompiling it reveals that the compiler treats the anonymous class like a regular class: it copies primitive variables into the inner class and passes references for object variables. Because the primitive copy is separate, modifying it inside the inner class would cause inconsistency with the outer variable, so the compiler forbids the modification.
Scenario Comparison
In Kotlin, the compiler wraps primitive variables, turning value passing into reference passing, which allows the inner class to modify the value without affecting the outer scope.
When a variable is not passed at all, Kotlin’s compilation shows no extra handling, confirming that the extra wrapping only occurs for captured primitives.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
