try-with-resources and null resource (original) (raw)

Rémi Forax forax at univ-mlv.fr
Thu Jan 27 01:09:02 PST 2011


On 01/26/2011 07:05 PM, Tim Peierls wrote:

On Wed, Jan 26, 2011 at 8:58 AM, Rémi Forax <forax at univ-mlv.fr_ _<mailto:forax at univ-mlv.fr>> wrote:

This code doesn't throw NPE when initializing r with null:

R r = get(); try { maybeUse(r); } finally { r.close(); } Nor should this code: try ( R r = get(); ) { maybeUse(r); } --tim Again, you're talking about implementation of the construct and not semantics of the construct. No, I am writing about what I think the semantics of the construct should be. I'm drawing an analogy between two constructs, one old, one new, that many users will see as similar, rightly or wrongly. Their expectations for the new construct's semantics will be shaped by this perception. I claim that most users won't expect NPE to be thrown immediately if the initializer is null, and that they will expect NPE to be thrown on the first attempt to dereference a null. They'll expect this because that's what happens in the analogous case. You can say the analogy is false, you can say that people should approach this construct as being radically different from try-finally, you can even say that most people are sloppy thinkers. But you can't change how they think by wishing, and it would be wrong to design the feature without taking such people into account. (You could also claim that I'm wrong about how the average user will respond to this new feature. But it doesn't sound like you're trying to make that case.) Perhaps it's because try-with-resources reuses the same keyword as try/finally, which doesn't help. To the contrary, I think this re-use of the try keyword will be very helpful to users trying to understand the new construct. I don't think most people will think about the new feature as being similar to things like switch or enhanced for. Switch takes an expression, and enhanced for uses a colon rather than equals, and thus doesn't look like a regular declaration. (If anything, they'll see a connection between t-w-r and the initialization clause of a traditional for loop.) To make things crystal-clear, what should you [sic] be the semantics of: using(R r = get()) { maybeUse(r); } if get() returns null? I think you're asking whether the users' expectations would be different if the construct used a different keyword. My answer: Maybe, but how is this relevant? People won't be thinking about alternative design choices when attempting to understand how the feature behaves. It is crystal clear that if you were designing this language feature you'd do it differently! :-) --tim

Tim, try-with-resources is different from try/finally (not radically I agree) because try-with-resources encompass the declaration of the variable. try-with-resource not only manage the resource but also the variable; by example it declare it final implicitly; storing the resource. That's why I think try-with-resources should throw a NPE when trying to assign a non existing (null) resource to the variable it manage.

Rémi



More information about the coin-dev mailing list