Josh M.
Josh M.

Reputation: 27821

Why does AutoClosaeble use try/catch semantics?

Java's AutoCloseable feature "reuses" try/catch semantics:

try (Stream x = ...) {
    // work with x
}

// x is out of scope and was auto-closed

I'm curious why they didn't introduce new semantics for this new feature. try implies that you expect the body to throw an exception at one point or another (or that it may). This seems much different to me than "instantiate this resource and close it when I'm done". That doesn't have anything to do with handling exceptions. Why not something like this...

with (Stream x = ...) { ... }

using (Stream x = ...) { ... } // I know, C# syntax

I'm not looking to fuel a debate, I want to know the reason the Java team decided to re-use try for this feature.

Upvotes: 0

Views: 125

Answers (2)

Turing85
Turing85

Reputation: 20195

The question is partially about a design choice in the Java language. Due to the nature of the question, this answer is only a partial answer of the question.

The try-with-resources does not reuse the try-catch concept, but the try-finally concept. Although seldom seen, try-finally has its uses. You could, for example, instead of explicitly catching an exception and re-throwing it, simply do some cleanup in the finally-block.1

The nature of AutoCloseable resources fits quite nicely in this use case: Open an AutoCloseable resource, do something and at the end close it, no matter what.

One could argue that starting this process through a try seems artificial. This, however, was a design decision of the language committe and is therefore not up to debate. If I had to guess, I would go with Michael's line of argumentation and say that they did not want to introduce a new keyword to stay backwards compatible.


1I am aware of the fact that was pointed out by @Radiodef, that a try-with-resources will be translated to a try-catch-finally. From my point of view, however, this is an implementation detail and a tool to specify the behaviour. It is not essential for understanding the semantics.

Upvotes: 2

Michael
Michael

Reputation: 44240

Java always tries its best to be backwards compatible. It's the cause of pretty much all of the weird or unfortunate aspects of the language today. It's happened a handful of times, but introducing a new keyword such as with or using was not a decision to be taken lightly. If they'd introduced a new keyword using, old code such as int using = 0 would not compile against the latest version of Java*

try-with-resources was basically introduced to reduce the verbosity of the following common pattern:

SomeResource resource;
try {
    resource = new Resource();
    resource.foo();
}
//optional catch
finally {
    if (resource != null) resource.close();
}

Because try was already involved before, adding additional functionality to try was the logical happy medium.


* Interestingly, a similar discussion was had over Java 10's var, which is not actually a keyword but a 'reserved type name' (so the semantics are slightly different):

Risk: source incompatibilities (someone may have used var as a type name.)

Upvotes: 3

Related Questions