There's a problem with box 2. If the IOException is thrown in the stream's constructor (FileNotFoundException) then there will be a NullPointerException if we try to call close!
InputStream in = null;
try
{
in = new FileInputStream(new File("test.txt"));
//do stuff with in
}
catch(IOException ie)
{
//SOPs
}
finally
{
try
{
if(in != null)
{
in.close();
}
}
catch(IOException ioe)
{
//can't do anything about it
}
}
Thanks, I didn't realize it's this bad. My only touch base with Java has been through Clojure.
This is just horrible. What braindead system forces you to check exceptions on closing a file handle? If everything failed silently and just produced 'null', the code would look like:
InputStream in = new FileInputStream(new File("test.txt"));
if (in) {
...dostuff...
in.close();
}
Now, that you can grasp with one glance. I'll trade the ability to write something like that with having to use malloc()/free() any day.
It's a much needed cleanup of something that's always resulted in clutter in my code. C# has had this feature for over a decade. Nice to see Java adding this since I have a lot of Java code to maintain. Like a lot of Java devs we're switching over to Scala for new projects and using vanilla Java for legacy code. Automatic resource management can be implemented trivially in Scala without the need for a new language feature to support it. Structural subtyping is awesome!
This is a welcome addition to java but I wish they had chosen a slightly different syntax. My main gripe is that its not clear what the lexical scoping rules are. Most likely the variable declared in the try is only available in the body of the try, not in the catch but its an extra thing to know. As opposed to
Now there are no new lexical scoping rules to understand. A lesser point is that I find the try(x = e) syntax ugly. It reminds me of the C-ism where a variable is set and tested in an if statement.
if (x = getline()){
...
}
Control flow and side effects should not be mixed, IMO.
It's not that simple. It doesn't just apply to stack allocated objects; resource ownership (in the sense of being responsible for "closing" the resource when you are yourself "closed") may and often does logically form a tree throughout the heap, and doesn't easily flatten to stack allocated objects without going further into allocating objects inline in other objects.
And when you introduce that, you have a problem of dealing with the difference between references to these inline objects: possibly on the stack or the heap, free-standing or embedded. If a reference escapes and outlives the lifetime of the object, you've created a potential dangling pointer, whereas in the normal Java or C# implementation you have at worst a semantic problem of having leaked a reference to a "closed" or disposed object. The GC won't collect it, but any operations on it will and should fail.
If you try and deal with this in the C++ way, you'll end up with far more confusion over objects passed around by reference, and objects passed around by value. Instead of the mechanism of passing being encoded by the type, it would be part of the control flow, and it would be easy to get into situations where you're working with a reference to a copy that was passed by value, and think you have a reference to the original; this is already a problem in C# to the degree that it is not recommended to create mutable value types.
TL;DR: what you suggest would create far more problems than it solves.
its nice but the issue for me is that it will be backwards compatible so the preJRE7 way of managing IO resources is also included , this means an even more bloated java api :-(
I think the only thing that was added to the API was a single interface called Closeable. Adding 1 interface to a library is hardly bloat. The change is essentially language support for a common syntax for resource management, not a new API.
[+] [-] jond3k|14 years ago|reply
[+] [-] yason|14 years ago|reply
This is just horrible. What braindead system forces you to check exceptions on closing a file handle? If everything failed silently and just produced 'null', the code would look like:
Now, that you can grasp with one glance. I'll trade the ability to write something like that with having to use malloc()/free() any day.[+] [-] JavaFirehose|14 years ago|reply
[+] [-] oconnor0|14 years ago|reply
[+] [-] Robin_Message|14 years ago|reply
[+] [-] jon6|14 years ago|reply
[+] [-] yason|14 years ago|reply
[+] [-] barrkel|14 years ago|reply
And when you introduce that, you have a problem of dealing with the difference between references to these inline objects: possibly on the stack or the heap, free-standing or embedded. If a reference escapes and outlives the lifetime of the object, you've created a potential dangling pointer, whereas in the normal Java or C# implementation you have at worst a semantic problem of having leaked a reference to a "closed" or disposed object. The GC won't collect it, but any operations on it will and should fail.
If you try and deal with this in the C++ way, you'll end up with far more confusion over objects passed around by reference, and objects passed around by value. Instead of the mechanism of passing being encoded by the type, it would be part of the control flow, and it would be easy to get into situations where you're working with a reference to a copy that was passed by value, and think you have a reference to the original; this is already a problem in C# to the degree that it is not recommended to create mutable value types.
TL;DR: what you suggest would create far more problems than it solves.
[+] [-] tbrownaw|14 years ago|reply
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] drstrangevibes|14 years ago|reply
[+] [-] grepgrep|14 years ago|reply