4

Generally speaking, the more I use immutable objects in Java the more I'm thinking they're a great idea. They've got lots of advantages from automatically being thread-safe to not needing to worry about cloning or copy constructors.

This has got me thinking, would an "immutable" keyword go amiss? Obviously there's the disadvantages with adding another reserved word to the language, and I doubt it will actually happen primarily for the above reason - but ignoring that I can't really see many disadvantages.

At present great care has to be taken to make sure objects are immutable, and even then a dodgy javadoc comment claiming a component object is immutable when it's in fact not can wreck the whole thing. There's also the argument that even basic objects like string aren't truly immutable because they're easily vunerable to reflection attacks.

If we had an immutable keyword the compiler could surely recursively check and give an iron clad guarantee that all instances of a class were immutable, something that can't presently be done. Especially with concurrency becoming more and more used, I personally think it'd be good to add a keyword to this effect. But are there any disadvantages or implementation details I'm missing that makes this a bad idea?

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • 1
    This sounds unnecessary and extremely limited in use. – Falmarri Jan 13 '11 at 00:35
  • 3
    @Falmarri on the contrary, I think immutable objects are used rather a lot. – Gordon Gustafson Jan 13 '11 at 00:43
  • C++ does the job with `const`. Personally, I would be very happy if Java had a similar keyword because it would allow you to mark a particular instance as immutable without having to muck around with things like (for example) `Collections.unmodifiableCollection`. The combination of `const` and `mutable` (to allow for lazy loading) seems to be a good one. – Cameron Skinner Jan 13 '11 at 00:48
  • 1
    @Falmarri immutable objects are used a heck of a lot - as I pointed out, especially with multi-threading becoming more and more popular immutable objects are becoming more of a good design practice (Bloch recommends them in effective Java, so it's not just me saying that.) Having a compiler guarantee that an object is immutable and therefore its contents are thread-safe is very useful indeed in a number of scenarios! – Michael Berry Jan 13 '11 at 00:49
  • 1
    An immutable object is thread safe because it's constant. What's wrong with public static final class members? – Falmarri Jan 13 '11 at 00:51
  • @Cameron Skinner Thinking about it, Java does actually have a reserved word "const" - it was added in the early days and "reserved for future use", of which there isn't yet any. So it's entirely possible const could be introduced as a keyword without breaking existing code! – Michael Berry Jan 13 '11 at 00:51
  • 1
    @Berry: Really? Awesome! Come on, Oracle! Get to it! – Cameron Skinner Jan 13 '11 at 00:52
  • 1
    @Falmarri That doesn't make an object thread safe at all, it just guarantees that the reference to that object won't change. It doesn't say anything about the object's contents. A public static final ArrayList is not an immutable ArrayList! – Michael Berry Jan 13 '11 at 00:53
  • @Cameron Skinner Yup, really! See here: http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html – Michael Berry Jan 13 '11 at 00:53
  • You can always subvert the language. Why do you need such assurances of thread safety? Just write thread safe code – Falmarri Jan 13 '11 at 00:59
  • 3
    @Falmarri: There are two points you're missing here. First, this isn't about thread safety (although thread safety is a good reason to have immutability). Second, the idea is for the language to have features that make it easier to write correct code. Saying "just write correct code" isn't really that helpful. – Cameron Skinner Jan 13 '11 at 01:04
  • 1
    @Falmarri: Spoken like someone who has never written any serious concurrent code nor been burned by subtle concurrency bugs. – Lawrence Dol Jan 13 '11 at 04:39
  • @Software Monkey: Actually I have both. But I've NEVER been bitten by a concurrency bug where I modified an object that I had wanted to be immutable. – Falmarri Jan 13 '11 at 07:10
  • 1
    I currently work on a little tool that may be of interest: Mutability Detector ( http://code.google.com/p/mutability-detector/ ). It's not perfect in it's analysis though, proving immutability is a really tough problem. – Grundlefleck Jun 22 '11 at 12:17

4 Answers4

5

In general, immutable objects should be preferred over stateful objects, and it's currently fairly difficult to make an immutable object in Java. In fact, most OO languages have poor support for immutable objects, while most functional languages take them for granted, such as F#, Haskell, and Clojure.

Adding an immutable keyword to Java could make code...

  • Easier to write. No messing with final and private, no accidentally adding a method that makes the class mutable, and possibly no manually marking the class final (subclasses can add mutable state).
  • Easier to read. You don't need to say that the class is immutable in English, you can say it in the code itself. An immutable keyword is a good step toward self-documenting code.
  • Faster (theoretically). The more the compiler knows about your code, the more optimizations it can make. Without this keyword, every call to new ImmutableFoo(1, 2, 3) must create a new object, unless the compiler can prove that your class can't be mutated. If ImmutableFoo was marked with the immutable keyword, every such call could return the same object. I'm pretty sure new must always create a new object, which makes this point invalid, but effective communication with the compiler is still a good thing.

Scala's case classes are similar to an immutable keyword. An immutable keyword was also being considered in C# 5.

Community
  • 1
  • 1
Gordon Gustafson
  • 40,133
  • 25
  • 115
  • 157
4

While making all fields final and also verifying any class references are also immutable is possible there are other situations where this becomes impossible.

  • What if your final class also includes some lazy loaded fields ? One would need further support for marking such fields as immutable and lazy.

  • Taking a look at java.lang.String with its array of chars[] how could the compiler really know for sure that it is immutable ? Everybody knows string is but another similar class could very easily include a method which updates an array. Further support would need to verify that once the field was set, no other instruction could "write" to the array. Before long this becomes a very complex problem.

In the end any such keyword if it did work might help, but it still does not mean programs are any better. Good design by good coders means better results. Dumb coders can still write crap even if the platform limits some pitfalls.

mP.
  • 18,002
  • 10
  • 71
  • 105
  • Good points there - I hadn't thought of lazily loaded fields and I agree it's not a trivial problem. I don't think those obstacles should be too much of a barrier though; there are ways around them (unless I'm not understanding something properly.) In terms of making programs better - I'm advocating it not so much to automatically improve crap code (it won't!) but instead to give good coders an easier job. It's very easy to miss something small at present that renders an otherwise immutable design wide open; that's the issue I'd hope such a keyword would address. – Michael Berry Jan 13 '11 at 01:06
  • Im sure if we sat down and thought about it the complexity of the problem explodes with many more edge cases, that in themselves introduce more edge cases. – mP. Jan 13 '11 at 01:23
  • Not truly valid points - the lack of a truly constant array is already a major problem, so const could help out there which solves the problem for String. And *barring explicit synchronization*, lazily loaded fields already and by definition make an object not thread-safe and thus not a candidate for being labelled immutable anyway. – Lawrence Dol Jan 13 '11 at 04:42
  • @SM My point was this is a complex problem, there are many special cases that creep and it probably never ends. Unfortunately java just is not really ready for this, there would need to be lots of keywords and stuff to make this work. Your comments about synchronization are an example of another pain that this approach would need to solve. – mP. Jan 14 '11 at 02:55
  • @Software Monkey that's not quite true - an object with lazily loaded field can still be threadsafe as long as the reassignment is atomic and any data races are benign. This is the case with java.lang.String's hashCode. – Grundlefleck Jun 22 '11 at 12:15
1

I'm a big fan of immutability, so in my opinion, absolutely. The advantages of immutability in OO programming are innumerable, and it shouldn't be the domain of just functional programming languages.

Martin Doms
  • 8,598
  • 11
  • 43
  • 60
1

IMHO, object-oriented frameworks (Java, .net, etc.) should include more array types: mutable array, immutable array, mutable array references, immutable array references, and read-only array references (a read-only reference could point to either a mutable or immutable array, but in neither case would allow writing). Without an immutable array type, it's hard to construct many efficient types in a way that can be proven to be immutable.

supercat
  • 77,689
  • 9
  • 166
  • 211