This is the first of a series of Java posts, occasioned by the fact that I’m doing some Java programming for the first time in a few years.
When I first started using C++, I thought that its insistence on supporting objects that aren’t held via pointers was, frankly, a little weird. The languages that I’d probably spent the most time with prior to C++ were C and Scheme. In C, you can of course pass structs by value and allocate them on the stack, but most of the time you pass structs via pointers. And in Scheme, there isn’t a notion of objects stored on the stack at all. In C++, though, the language support for objects on the stack is front and center: the copy constructor and the assignment operator are so important that the compiler will provide them for you if you don’t define them yourself, and referenecs are omnipresent, used to get the efficiency of passing via pointer without having to explicitly take an address. So I wondered if it was a good idea, or if it was a misguided legacy of of structs in C. Why not use a simple syntax for referring to C++ objects but have them be heap-allocated behind your back, like in Scheme?
I got used to it, though. Actually, you construct objects directly in C++ much more often than you construct structs directly in C: you construct objects on the stack all the time, and it’s quite common for data members of classes to be classes. (As opposed to C, where it’s not nearly as common for a struct to have a struct as a data member.) Of course, you could have the same appearance while having heap allocation everywhere behind your back, but the more I thought about it, the less appropriate that seemed for a C offshoot: it would go against the language’s obsession with efficiency, and it might not be possible without garbage collection. (Which is another thing that I used to love, but learning C++ has made me realize that garbage collection is much more of a mixed bag than I used to think. Maybe I’ll post on that some other time.)
And now I’m using Java, and I find myself brainwashed by C++. I’m constantly worrying about returning objects – is it safe to return them without cloning them, or am I exposing too much of my internal implementation? (Which has bitten me: my last Java project involved writing a toy compiler, and program-level testing turned up something like two or three bugs that made it through the unit tests; not cloning was at the root of one of them.) And typing ‘new’ all the time bugs me. And while Java does have an analogue of the copy constructor, namely Object.clone(), it’s not nearly as easy to use. At least I think it isn’t, though I haven’t implemented it frequently enough to be sure; the techniques and division of responsibilities involved just seem bizarre to me.
Still, I’m sure I’ll get used to it soon enough, and the fact that C++ has both references and pointers has to be a sign of a design flaw. Probably Object.clone is also a design flaw, and (assuming that I accepted garbage collection) I’d ultimately prefer a language that was more like Java but with Object.clone behaving more like a C++ copy constructor. For that matter, I suppose there’s nothing preventing me in Java from doing copy constructors of my own; it might be tedious without compiler support, though. Maybe I’ll give it a try, and see if I can end up at a happy medium.
There are no revisions for this post.