2

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?

6
  • If webServer is null it will throw an NPE. Commented Jun 24, 2022 at 8:41
  • 3
    you could check directly if this.webServer != null without creating new local variable webServer Commented Jun 24, 2022 at 8:42
  • 1
    @mohammedkhan you reach that point only after checking that this.webserver is not null anyway Commented Jun 24, 2022 at 8:42
  • 4
    @f1sh it does, guess what happens if between the null check the webServer field is set to null by another thread, you get an NPE, even if you did the null check. Commented Jun 24, 2022 at 8:46
  • 3
    A field can be changed between two reads, by code you’re not seeing, the local variable can not. Commented Jun 24, 2022 at 8:48

3 Answers 3

7

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:

  1. your thread: this.webServer != null -> true
  2. another thread: this.webServer = null
  3. your thread: this.webServer.stop() -> possibly results in NullPointerException (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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.