Why anonymous inner class parameters must be final
Recently, when I wrote some anonymous inner classes, I felt a little difficult to understand, so I reviewed this part again. I found some points that I didn’t notice before - the formal parameters of the anonymous inner class must be prefixed with final (unless the anonymous inner class does not use it)
So, how to understand the principle behind this matter?
How inner classes work
First, think about how inner classes work. We know that after the internal class is successfully compiled, it will generate a new class file.
The class file only retains references to external classes.
For example, when the parameters passed in by the outer class need to be called by the inner class, it looks like it is called directly:
1 |
|
But in fact name is not directly called by the inner class, in fact it looks like this after java compilation:
1 |
|
Therefore, from the above code, the internal class does not directly call the parameters passed in by the method, but the internal class backs up the passed parameters to its own interior through its own constructor, and the internal method call is actually its own properties instead of parameters of outer class methods!
With this understanding, it is easy to figure out why final is used.
Assuming that the inner class modifies the values of these parameters, the values of the original parameters do not change, which affects the consistency of the parameters.
From the programmer’s point of view, this parameter is the same, but if the value of the parameter is changed in the inner class, but the value is not changed when the external call is made, it may be very confusing, so in order to avoid this kind of embarrassing problem, the compiler designers set the parameters that can be used by inner classes to be final.
How anonymous inner classes work
OK, what’s the difference between an anonymous inner class and an inner class - it has no name.
There is no name, so it is constructed with the default no-argument constructor. If parameters are required, then give him a constructor with parameters.
1 |
|
Look, here the parameter of the getInner method is final, the reason is the same as the reason for adding final to the inner class part before.
Sometimes you can also not add final
When can you not add final? If the inner class does not use it, you can not add final, which is easy to understand:
1 |
|