9

give me please examples where I could see advantages of immutable objects. Info I found in internet are concentrated in threads. I don't know about threads yet. would be great if the examples would use simple principles

2
  • The main advantage in Java is in the use of threads. It may not make sense to you until you have a basic understanding of threads. Also it makes more sense when you have experience of programming and the things which can go wrong. esp on large complex projects. Apr 13, 2011 at 16:46
  • It can simplify your understanding of interactions in your code, if you know that an object has a state that can not be changed from the outside.
    – wkl
    Apr 13, 2011 at 16:48

8 Answers 8

18

Immutability is important in multi-threaded programs, because then you know that one thread won't corrupt a value used in another thread. But it's also useful in a single-threaded program.

Here's a simple example:

Integer i=Integer.valueOf(17);
foo(i);
bar(i);

You might well want to know, What value is passed to bar()?

Suppose that foo() is a big, complex function. In this example, I know for an absolute fact that when foo completes, i is still equal to 17, because an Integer is immutable. Were that not true, I would have to study foo to tell if it might be changed or not.

Here's a slightly more complex example. Suppose I have some object that resembles an Integer, but is mutable. Let's call it MutableInteger. Then say I write this:

MutableInteger currentInventory=findQtyInInventory();
MutableInteger neededInventory=currentInventory; // copy current for starters
... bunch of other code ...
neededInventory.subtract(allocatedToSales);
currentInventory.add(arriving);
... bunch of more code ...
if (neededInvenory.compareTo(currentInventory)>0)
  display("Shortage!");

Do you see the problem with the above? neededInventory and currentInventory point to the same object. All the adds and subtracts are really acting on the same value, not two different values, so when we get to the test, it will always be equal. The above code would never work if the objects are mutable. If they are immutable, the adds and subtracts would have to return a result object rather than updating in place, and that would work.

Years ago I used a Fortran compiler where integers WERE mutable. We had a function that accepted several parameters, one of them an integer. In some rare cases, the function updated the integer. Then one day someone wrote a call to this function passing the constant "2" as the integer. The function decided to update the parameter, thus changing the "constant" 2 to 1! Every other place in the program that used a constant 2 now mysteriously got the value 1 instead. This took a long time to debug.

3
  • 1
    Wow, I thought I was the only one who could remember that far back into Fortran. Jul 1, 2011 at 21:15
  • 1
    So this would be clearer if it was stated that Java must therefore ALWAYS pass by reference, and not copy. So all passed values can be modified UNLESS they are immutable. I think it's PHP, though, that passes everything by value to save copy time and memory, just like Java, BUT if the object is modified, then it is copied and the function/method then does not modify the object.
    – Dennis
    Sep 6, 2012 at 1:47
  • @Dennis Well, there are times when you want to be able to modify a passed-in object. For example, create an order object with the list of items ordered, then pass it to a function that calculates sales tax and fills this in to the order object. It's not so much immutable=good / mutable=bad, as knowing what you're doing in each case. There's something to be said for languages that require you to say whether you are passing by reference or by value and thus allow and require you to explicitly decide.
    – Jay
    Sep 6, 2012 at 17:36
10

It's not a concept that can be usefully explained with examples. The advantage of immutable objects is that you know their data cannot change, so you don't have to worry about that. You can pass them around freely without having to remember whether a method you pass them to could change them in a way your code is not prepared to handle. That makes working with immutable data easier.

With multiple threads, this advantage is just more important because bugs based on multiple threads changing data in ways it's not supposed to be changed are usually not reproducible - they depend on timing and thus sometimes happen and sometimes not, which makes them very hard to analyze and fix.

2

As you already know, it's a great pattern for multithreading.

It also means much better encapsulation. You can pass those objects around and share them and you never, ever have to worry that someone changes your object's state.

There are some great examples in Java core library. Number subclasses are one, but I think the best example is String. You pass them around, concatenate, get substrings etc. and never need to think about other places. If it was mutable like C/C++ char[], you would always need to keep that in mind.

For the same reason it also leads to more readable and maintainable code. No need to care about other users of the object.

Both these reasons lead us to another important pattern called Value Object. In brief, it makes sense when you care about some particular value (a date, a number, a string, an interval, money, or some slightly more complex objects if you need), but the value itself has no identity, i.e. it has exactly the same meaning regardless of context.

1

As Java returns by value (i.e. object references are returned from methods), if for example I return a String like so:

private String myString = "foo";

public String getString() {
    return this.myString;
}

and the String class wasn't immutable, then the caller of getString() could modify myString, which may not be the desired behaviour; other parts of the system might not want or expect myString to change. So the caller can only change the object which myString points to, not myString itself.

5
  • 'By value' is a reference? I thought they were the opposite of each other?
    – Dennis
    Sep 27, 2012 at 19:52
  • You have to remember that in the example above, myString is actually a reference to a String object, not the object itself. So returning this.myString returns, by value, the reference to myString.
    – Matt Dunn
    Nov 6, 2013 at 17:12
  • According my information , Java strings are immutable so I dont think the caller can modify the original private object myString. When he tries to modify it a new String obj is created . Feb 2, 2015 at 7:06
  • 1
    @Vikram Bhat: Yes, that was the point of my answer. If Strings were not immutable, then the caller would be able to modify the original myString.
    – Matt Dunn
    Feb 2, 2015 at 10:40
  • @Dunnie ok then , sorry misinterpreted it Feb 2, 2015 at 12:30
1

It's kind of tautological, but the main advantage of immutable objects is that they can't change. When objects can change, you have to think about what might happen with them. You have to think about how, when and why you want to change them. You have to think about what other code in your application might have access to the same object, and what it might change without you knowing. Immutable objects effectively reduce the number (and granularity) of "moving parts" you have to juggle in your system and make your life easier.

1

Immutable objects are useful when objects are generally shared - not just with threading, but in single-threaded programs also where an object has many clients.

For example, String is probably the most used immutable object in Java. It's immutable to stop users of that string from changing it's contents. If String was mutable, it would mean each user would have to create a unique copy of that string to ensure no-one else was changing it.

Immutable data also has security implications. For example, a security token associated with a user should be immutable, otherwise a rogue program could easily change the user associated with that token.

0

The main idea here is to make your classes thread safe by using immutable objects. I think this article is a good read on this.

Hope this helps!

0

A good example is the String class:

A good summary of reasons for immutable objects can be found here

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