One of the reasons why many programmers prefer C++, is that it features “deterministic resource deallocation”. Reading this phrase, I often ask myself: “Do other languages feature non-deterministic resource deallocation?” In my opinion, non-determinism is not a feature, but rather a shallow understanding of the functionality of C++ destructors and the purposes (and consequently limitations) of garbage collection.
What is a destructor in C++? A simple answer might sound like this: “A destructor is a function, which is invoked right before freeing an object’s memory.” Consequently, one might ask: “How can I execute code in Java before freeing an object?” And we arrived at finalizers, which have no use case in a purely managed environment.
The reason for this confusion is, in my opinion, thinking on a wrong level of abstraction. Garbage collected languages typically provide no way to directly manage memory – memory management is below the abstraction level of the language. Why would you bind your program’s behavior to implementation details of the language?
In the following, this post explores the possibilities of C++-like resource management in languages featuring automatic memory management. First, we take a closer look at the functionality of C++ destructors, and consider alternatives. Finally, I propose an implementation of an atypical feature of C++ destructors in Java 8, and discuss its limitations.