I admit, I like the "RAII" approach of C++ -- "Resource Acquisition Is Initialization". The object itself is responsible for what to do when it goes away. In C++ this means when the resource-using variable leaves scope. The class that implements the resource usually does that in the desctructor.
In Java you can not be sure whan the variable using the resource goes aways-- so need an "finally" at the calling site.
There are lots of discussions about beauty, clarity, stupidity and other objective matters about this. I just want to point out, what it is all about -- so, if you happen to invent a new language you do the right thing...
Let "a resource" be something that you "acquire" at some point in time, and you have to "release" at another point in time. The thing about many resources is, that you need to release them often at a very specific time. Eg. closing a file, to be sure the last line is written before your program crashes, closing the database connection before you open the next, straining your pool, removing a button from its parent window, so it does not "hang around"... you get my drift.
In C++ the standard method is, to write a class and the "acquire" takes place in the constructor and the "release" in the destructor. Using the resource then means that you declare the instance in the scope where you need the resource. When its scope is left in any way, the resource if released.
class CFile {
public:
CFile(const string& name) {
f = fopen(...);
}
~CFile(const string& name) {
fclose(f);
}
};
void main()
{
CFile myfile("persons.txt");
...use...
}
Straightforward C++, no magic. Java puts the "close()" on the callers side. Same straightforwardness, different approach.
class CFile
{
CFile(String name) {
f = fopen(name); /* fopen()? you know what I mean */
}
void close() {
fclose(f); /* pseudo-code again */
}
static void main(String args[]) {
CFile myfile("persons.txt");
try {
...use...
}
finally {
myfile.close();
}
}
}
This is simple enough and not difficult at all. Imagine that you now juggle with many "CFile"s, a couple of Database Connections, some Pools and lots of Windows. Some rely on each other, i.e. that they close/release/destroy in the correct order. There may be a lot of nested try-finallies, which might get you out of bounds -- the right bound of your editor, I mean.
Look at an old
Herb Sutter Blog entry to get an opinion from a C++ guru.
Guideline: When inventing a new language look at the RAII concept of C++ and see if you like it.
Guideline: And if you do a garbage collecting language, take a look at C#'s "using" or Pythons "with" directive, maybe you like that, too.
(quote from Pythons documentation)
with open("hello.txt") as f:
for line in f:
print line
In older versions of Python, you would have needed to do this to get the same effect:
f = open("hello.txt")
try:
for line in f:
print line
finally:
f.close()
The latter one is very much like it would be in Java as well.