I would like some clarification beyond what I have found online involving final variables and inner classes. Specifically, my question pertains to why global variables are ok to use in inner classes rather than why certain variables need to be final. Please let me know if you can provide clarification/corrections on my reasoning.
In the following examples, I created an inner class, and from what I believe “i” is duplicated when the anonymous inner class which is of the type View.OnClickListener is created. When the inner class is created the variables must be made final more as a note to the user than something that is really necessary. From what I gather, this is just like when you pass a variable into a method. Those variables are duplicated since Java is a pass by value language. After the method finishes the copies are lost and no changes to the originals values are saved. Let’s just stick to the int to keep it simple for this example.
Button b;
int j = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b=findViewById(R.id.button);
int i = 0;
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
i++;
j++
}
});
}
Is the forcing of final is more to safe guard the programmer since the value of i (in this example) will never actually be changed?
Is the final modifier not necessary for j because global variables are not duplicated when the inner class is created? Is this because they already exist for all classes that are contained within, so duplication do not take place?
I will use this example in my answer :
The level of accessibility does everything. Such as
jis a global variable that will stay until the object exist, it will always be here.The lambda expression (
() -> {}) will use the object and keep it.For
i, the variable will be removed at the end of the method execution. Such as the lambda is not runned by the method itself, the JVM don't know the area of the variable.Without final, it consider that the variable isn't used my lambda and can delete it to get back memory space.
With it, it consider it should wait until all sub-method are finished. So until all lambda's in lambda's have ended.