Fundamentals 5 min read

Why Java’s Anonymous Inner Classes Restrict Variable Changes (and Kotlin’s Trick)

The article explains why Java’s anonymous inner classes still forbid modifying captured primitive variables after Java 8, how the compiler enforces this by copying values, and why Kotlin can modify them by using reference‑style wrappers.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Java’s Anonymous Inner Classes Restrict Variable Changes (and Kotlin’s Trick)

During development, developers often assume language features are similar across languages, but notable differences emerge when using multiple languages.

Phenomenon Description

Before Java 8, using an external variable inside an anonymous inner class required the variable to be final , otherwise the compiler reported “Cannot refer to a non-final variable …”. After Java 8 the warning disappears, yet attempts to modify the variable still produce an error: “Variable 'num' is accessed from within inner class, need to be final or effectively final”. Kotlin, however, allows direct modification of primitive variables inside anonymous inner classes.

Even after Java 8, when you try to change the variable, the compiler still reports an error, confirming the restriction remains.

The error message becomes “Variable 'num' is accessed from within inner class, need to be final or effectively final”, indicating the variable cannot be altered. In contrast, Kotlin imposes no such limitation.

Kotlin’s compiler wraps primitive values, turning value passing into reference passing, so internal modifications do not affect the outer variable.

Cause Analysis

Inspecting the compiled output of javac reveals several .class files. The file named TestInnerClass$1.class corresponds to the anonymous inner class. Decompiling it shows that the compiler treats the anonymous class like a regular class, generating a constructor that receives both a reference to the outer class and copies of the captured primitive variables, while passing references for object variables. Consequently, the primitive variables cannot be modified inside the inner class because doing so would cause inconsistency with the outer scope.

The decompiled view confirms this handling.

Scenario Comparison

Why can Kotlin modify primitive values inside an anonymous inner class? Decompiling Kotlin’s compiled code shows that Kotlin wraps primitive values, converting value passing into reference passing, allowing internal modifications without affecting the outer variable.

When a variable is not passed at all, Kotlin’s compiler does not add unnecessary wrappers.

Thus, Java’s restriction stems from how the compiler copies primitive values into the anonymous class, while Kotlin’s approach uses reference semantics to avoid the limitation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaCompilationKotlinVariable ScopeAnonymous Inner Class
Java Backend Technology
Written by

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!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.