What is the effect of declaring a final variable in methods?

Classic simple server example:

class ThreadPerTaskSocketServer { public static void main(String[] args) throws IOException { ServerSocket socket = new ServerSocket(80); while (true) { final Socket connection = socket.accept(); Runnable task = new Runnable() { public void run() { handleRequest(connection); } }; new Thread(task).start(); } } } 

Why declare Socket as final ? Is it because the new Thread that processes the request can refer to the Socket variable in the method and raise some ConcurrentModificationException ?

+7
java methods concurrency final
source share
6 answers

In this case, the variable must be final in order to be used inside the anonymous Runnable binding.

This is because this object will exist when the variable has already gone out of scope and thus disappeared. The object receives a copy of the variable. To hide this, the variable must be final so that no one can expect that changes in one copy will be visible to another.

+13
source share

Consider the following example:

 class A { B foo() { final C c; return new B() { void goo() { // do something with c } } } } // somewhere else in the code A a = new A(); B b = a.foo(); b.goo(); 

If c was not final when you reach b.goo() , this will point to trash, since this c will collect garbage - a local variable after the method call completes.

+3
source share

You need to declare it final, and not just. Without this, the compiler cannot use it in an anonymous implementation of the Runnable class.

+2
source share

Declaring a final method variable means that its value cannot change; that it can only be installed once. How is this applicable in this context?

I have been aware of this limitation with anonymous classes for some time, but I never understood why. I see that no one still makes any of the answers so far. some googling climbed lower, which, I think, explains this well.

An anonymous local class can use local variables because the compiler automatically gives class a a private instance field to store a copy of each local variable used by the class. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, the local class is not really variables, but just their own copies. The only way this can work correctly is if the variables are declared final so that they are guaranteed not to change. Given this guarantee, the local class is confident that its internal copies of the variables accurately reflect the actual local variables.

loan for: http://renaud.waldura.com/doc/java/final-keyword.shtml#vars

Of course, something that I think the compiler really should be hiding from the developers is not obvious either.

+2
source share

Local variables are not shared between threads. (A local variable is part of the activation record, and each thread has its own activation record).

Since connection is a local variable, it is not possible to share it between threads. Since it is not shared between threads, you need to make it final , so it does not matter that it is a local variable (it can be seen more as a constant value).

0
source share

It is not intended to solve the ConcurrentModificationException problem. Any local variable used inside a method-nested class (for example, an anonymous inner class) must be declared final. See a similar discussion from last week here:

method of local inner classes accessing local variables of a method

In fact, in the case of threads, there is little contribution to thread safety; There will be no visible problems with the final variable between threads. However, this does not guarantee thread safety.

0
source share

All Articles