Classic example of a simple server:
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 should the Socket
be declared as final
? Is it because the new Thread
that handles the request could refer back to the socket
variable in the method and cause some sort of ConcurrentModificationException
?
In this case, the variable must be final to be used inside the anonymous Runnable
implmentation.
This is because that object will exist when the variable has already gone out of scope and has thus disappeared. The object gets a copy of the variable. In order to hide this, the variable must be final so that nobody can expect changes in one copy to be visible to the other.
Consider this 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()
, it would point to junk, since that c would be garbage-collected - A local variable after the end of a method call.
You need to declare it final, not only should. Without that, the compiler cannot use it in the anonymous Runnable class implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With