Easy Tutorial
❮ Android Tutorial Autocompletetextview Android Tutorial Webservice ❯

Why can only local inner classes and anonymous inner classes access final local variables?

Category Programming Techniques

Recently, while studying inner classes, I had a doubt: local inner classes and anonymous inner classes can only access final local variables. After reading several blog posts, I understood a lot.

First, let's look at an example of a local inner class:

Example

class OutClass {
    private int age = 12;

    public void outPrint(final int x) {
        class InClass {
            public void InPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }
        new InClass().InPrint();
    }
}

Here, there is an outer class OutClass and an inner class InClass. The inner class accesses a local variable x from a method in the outer class. Here, x must be final; otherwise, an error will occur:

Cannot refer to a non-final variable x inside an inner class defined in a different method

Let's analyze this issue:

The root cause is the variable's lifecycle in the scope;

First, it is important to know that the inner class and the outer class are at the same level, and the inner class will not be destroyed along with the method's execution.

This creates a problem: when the method of the outer class ends, the local variable will be destroyed, but the inner class object may still exist (it will only die when no one refers to it anymore). Here lies the contradiction: the inner class object accesses a non-existent variable. To solve this problem, a copy of the local variable is made as a member variable of the inner class, so that after the local variable dies, the inner class can still access it, actually accessing the "copy" of the local variable. This seems to extend the lifecycle of the local variable. We can experiment by decompiling the generated .class file:

In the command line window, first execute the command javac OutClass.java to compile, and you will get two files: OutClass$1InClass.class, OutClass.class:

javap is a Java class file disassembler that can decompile and view the bytecode generated by the Java compiler.

Here we can execute the command javap -private OutClass$1InClass to decompile, -private means to display all classes and members, and after execution, we will get the following result:

It can be seen that the local variable in the method is indeed copied as a member variable of the inner class for use.

The problem arises again: when copying the local variable as a member variable of the inner class, it is necessary to ensure that these two variables are the same, that is, if we modify the member variable in the inner class, the local variable in the method must also change, how to solve the problem?

Set the local variable to final, after initializing it, I don't let you modify this variable anymore, which ensures the consistency between the member variable of the inner class and the local variable of the method. This is actually a compromise.

If the variable is final:

-

If it is a primitive type, its value cannot be changed, ensuring that the copy is the same as the original local variable;

-

If it is a reference type, its reference cannot be changed, ensuring that the copy and the original variable refer to the same object.

This keeps the local variable and the copy established within the inner class consistent.

**Click to share notes

Cancel

-

-

-

❮ Android Tutorial Autocompletetextview Android Tutorial Webservice ❯