One thing from C++ that I miss in Java is the notion of ‘const’. As I commented earlier, I’m always worried when I return an object that I’m exposing too much of my internals. If I had const to help, it might not be so bad, because I could return const objects, but I don’t have that to help me.
Still, while I like const, it’s a bit of a special case, so maybe I can accept it in the name of simplification. What bothers me more is that similar flaws show up in the library, in situations where they could be easily avoided. In particular, unlike the STL, there’s no iterator / const_iterator distinction. In Java, the Iterator interface has a remove operation; while the documentation marks it as an “optional operation”, saying that you can throw an UnsupportedOperationException, that’s not the way interfaces should work: if a class doesn’t support an operation, then that operation shouldn’t be part of its interface! That’s what static typing is all about!
Java’s Iterator interface is actually a little weird. I’m not that thrilled with the idea of combining the notions of retrieving the current element and advancing the iterators into a single operation. I guess I’ve started to buy into the notion of “Command/Query Separation”; while it’s not as important in Java as in C++, because you don’t have potentially expensive/exception-throwing copy constructors to deal with, it still seems a little unclean to put the two together, and couldn’t there be situations where you want to retrieve the current element without advancing the iterator? Also, it makes for loops look funny, because the third part is missing.
Of course, Java 5 introduced a new kind of for loop, saving you the trouble of doing all the checking and advancing yourself. Which I will also grumble about – it actually doesn’t take an Iterator as an argument! Instead, it takes a Collection (well, an Iterable) as an argument, which it gets an Iterator from (behind your back) by calling its iterator() method. This may save you typing much of the time, but it limits your flexibility – what if, for example, you want to iterate over elements of a list in reverse order? (Hmm: it looks like Java lists don’t actually support doing that by returning a separate reverse iterator object – instead, they return a ListIterator which allows you to go both forwards and backwards. Which is a useful capability, but it would still be nice at times to turn one into a normal Iterator running backwards.) Or what if you wanted to have an InputStream-like class that provided an Iterator interface?
The Java book I was reading touched on this issue, I think – they comment that Java frequently uses Collections where other people expect Iterators, on the grounds that that’s usually what you have around, and in a general interface, you might as well expose the more powerful notion. Which is a reasonable argument, I suppose, for returning Collections where I might be tempted to return an Iterator. (Which gives rise to the same worries about constness that I complained about above, with the same solution: the modification operations for Collection are “optional”, and the language even provides an unmodifiableCollection() function to turn a modifiable Collection into an unmodifiable one.) But it’s not a reasonable argument for interfaces to require a Collection when they only need the functionality of an Iterator: you’re just throwing away generality in that case.
Sigh. I guess, after the STL, most collection frameworks are likely to be a bit of a let-down.
Post Revisions:
There are no revisions for this post.