84

How does the try-with feature work for AutoCloseable variables that have been declared null?

I assumed this would lead to a null pointer exception when it attempts to invoke close on the variable, but it runs no problem:

try (BufferedReader br = null){
    System.out.println("Test");
}
catch (IOException e){
    e.printStackTrace();
}
flakes
  • 21,558
  • 8
  • 41
  • 88

1 Answers1

113

The Java Language Specification specifies that it is closed only if non-null, in section 14.20.3. try-with-resources:

A resource is closed only if it initialized to a non-null value.

This can actually be useful, when a resource might present sometimes, and absent others.

For example, say you might or might not have a closeable proxy to some remote logging system.

try ( IRemoteLogger remoteLogger = getRemoteLoggerMaybe() ) {
    if ( null != remoteLogger ) {
       ...
    }
}

If the reference is non-null, the remote logger proxy is closed, as we expect. But if the reference is null, no attempt is made to call close() on it, no NullPointerException is thrown, and the code still works.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • 3
    Haha, the use-case you just added is what made me ask the question in the first place! Thanks! – flakes Feb 12 '16 at 21:22
  • 1
    No way! That is wild. I just made it up. – Andy Thomas Feb 12 '16 at 21:24
  • Well,. different variable types, but same structure :p – flakes Feb 12 '16 at 21:25
  • 2
    Still cool! Nice to see the language designers thought of this case. – Andy Thomas Feb 12 '16 at 21:27
  • I typically throw a caught exception if there is a problem where I would otherwise return null. It is a little much to have a catch block for every try-with-resources, but then having a null check is about the same. In fact, null check is actually a little slower (marginally) in optimal conditions, which is why I settled on throwing caught exceptions. – searchengine27 Jun 19 '19 at 15:34
  • @searchengine27 - My understanding is that an exception can be more expensive to *throw* than returning null. A null return value could be a normal case, or an exceptional case. My example is for the former. Exceptions are best used for the latter. – Andy Thomas Jun 19 '19 at 17:44
  • 1
    Yes exceptions are more expensive to throw. But typically, in Java as opposed to languages like Python, exceptions aren't used for control flow and are used for problems. Catch blocks have no performance impacts in nominal cases. So the reason I like it is because in nominal cases it's cheaper. Again, we're talking marginal gains because it's an extra couple assembly statements under the hood for a null check, but my typical stance on computing is 'every little bit counts'. – searchengine27 Jun 20 '19 at 17:34