This is something I see in Spring Boot code for example (in the catch
block with webServer
variable):
@Override
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}
Why not just doing this.webServer.stop()
?
What is the purpose of local variable webServer
?
CodePudding user response:
The main purpose of the assignment is to avoid producing a NullPointerException
when the this.webServer
is set to null
by a concurrent thread after the null-check and before the webServer.stop()
call.
That is, without a local variable:
- your thread:
this.webServer != null
-> true - another thread:
this.webServer = null
- your thread:
this.webServer.stop()
-> possibly results inNullPointerException
(depending on visibility of change in step 2, this might not always happen; a race condition).
In other forms of code, assigning a field to a local variable can also have performance benefits compared to repeatedly referencing a field.
CodePudding user response:
If null-check would be done on the instance variable another thread could potentially nullify this.webServer
after it was checked for null but before webServer.stop();
is called. This answer describes this behavior well.
CodePudding user response:
If you're working in a multiple threaded environment, the same variable might have different value for threads. In such cases, if code env is not synchronised you'll get an NPE.
If you want to use this.webServer.stop()
, make sure your read and write on this variable is synchronized at each place, otherwise use local variables as suggested.