Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

During my first implementation extending the Java collection framework, I was quite surprised to see that the collection interface contains methods declared as optional. The implementer is expected to throw UnsupportedOperationExceptions if unsupported. This immediately struck me as a poor API design choice.

After reading much of Joshua Bloch's excellent "Effective Java" book, and later learning he may be responsible for these decisions, it didn't seem to gel with the principles espoused in the book. I would think declaring two interfaces: Collection, and MutableCollection which extends Collection with the "optional" methods would have led to much more maintainable client code.

There's an excellent summary of the issues here.

Was there a good reason why optional methods were chosen instead of the two interfaces implementation?

share|improve this question

migrated from stackoverflow.com May 20 '11 at 15:01

This question came from our site for professional and enthusiast programmers.

add comment

4 Answers

up vote 15 down vote accepted

The FAQ provides the answer. In short, they saw a potential combinatorial explosion of needed interfaces with modifiable, unmodifiable, delete-only, add-only, immutable (for threading), and so on for each implmentation.

share|improve this answer
4  
All of this would have been avoided if Java had a const keyword like C++. –  Etienne de Martel May 20 '11 at 15:17
    
@Etienne: Better would be metaclasses like Python. Then you could programmatically build the combinatorial number of interfaces. The problem with const is that it only gives you one or two dimensions: vector<int>, const vector<int>, vector<const int>, const vector<const int>. So far so good, but then you try implementing graphs, and you want to make the graph structure constant, but the node attributes modifiable, etc. –  Neil G May 20 '11 at 20:54
1  
@Etienne, yet another reason to bump up "Learn Scala" on my to-do list! –  glenviewjeff May 21 '11 at 2:30
1  
What I don't understand is, why they didn't make a can method that would test if an operation is possible? It would keep the interface simple and fast. –  Mehrdad May 21 '11 at 4:18
1  
@Etienne de Martel Nonsense. How would that help in the combinatorial explosion? –  Tom Hawtin - tackline May 21 '11 at 20:53
show 1 more comment

It sounds to me like the Interface Segregation Principle wasn't as well explored back then as it is now; that way of doing things (i.e. your interface includes all the possible operations and you have "degenerate" methods that throw exceptions for the ones you don't need) was popular before SOLID and ISP became the de-facto standard for quality code.

share|improve this answer
1  
Why a downvote? Somebody doesn't like the ISP? –  Wayne M May 21 '11 at 12:11
    
It's also worth noting that in frameworks that support variance there is a HUGE advantage to segregating those aspects of an interface which can be covariant or contravariant from those which are fundamentally invariant. Even absent such support, in frameworks that don't use type erasure there would value in segregating aspects of an interface which are type-independent (e.g. allowing one get the Count of a collection without having to worry about what types of items it contains), but in type-erasure-based frameworks like Java that's not such an issue. –  supercat Jul 16 '12 at 15:47
add comment

IMO, there is not a good reason. The C++ STL was created by Stepanov in the early 80's. Although it's usability was limited by the awkward C++ template syntax, it is a paragon of consistency and usability when compared to the Java collection classes.

share|improve this answer
add comment

I would attribute it to the original developers just not knowing better back then. We've come a long way in OO design since 1998 or so when Java 2 and Collections were first released. What seems like obvious bad design now wasn't so obvious in the early days of OOP.

But it may have been done to prevent extra casting. If it was a second interface you'd have to cast your collections instances to call those optional methods which is also kind of ugly. As it is now you'd catch an UnsupportedOperationException right away and fix your code. But if there were two interfaces you'd to have to use instanceof and casting all over the place. Perhaps they considered that a valid tradeoff. Also back in the early Java 2 days instanceof was heavily frowned upon due to it's slow performance, they might have been trying to prevent over use of it.

Of course this is all wild speculation, I doubt we could ever answer this for sure unless one of the original collections architects chimes in.

share|improve this answer
3  
What casting? If a method returns you a Collection and not a MutableCollection, it's a clear sign that it is not meant to be modified. I don't know why anybody would need to cast them. Having separate interfaces means you'll get those kind of errors at compile time instead of getting an exception at run time. The earlier you get the error, the better. –  Etienne de Martel May 20 '11 at 15:15
1  
Because that's way less flexible, one of the largest benefits to the collection library is that you can return the high level interfaces everywhere and not worry about the actual implementation. If you're using two interfaces you're now more tightly coupled. In most cases you'd simply want to return List, and not ImmutableList because you usually want to leave that to the calling class to determine. –  Jberg May 20 '11 at 18:05
2  
If I give you a read only collection, that's because I don't want it to be modified. Throwing an exception and relying on documentation feels a hell of a lot like a patch. In C++, I would simply return a const object, instantly telling the user that the object cannot be modified. –  Etienne de Martel May 20 '11 at 18:43
3  
1998 wasn't "early days of OO design". –  quant_dev May 21 '11 at 9:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.