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.

If immutable objects¹ are good, simple and offer benefits in concurrent programming why do programmers keep creating mutable objects²?

I have four years of experience in Java programming and as I see it, the first thing people do after creating a class is generate getters and setters in the IDE (thus making it mutable). Is there a lack of awareness or can we get away with using mutable objects in most scenarios?


¹ Immutable object is an object whose state cannot be modified after it is created.
² Mutable object is an object which can be modified after it is created.

share|improve this question
32  
I think that, apart from legitimate reasons (as mentioned by Péter below), "lazy developer" is a more common reason than "stupid" developer". And before "stupid developer" there's also "uninformed developer". –  Joachim Sauer Jun 6 '12 at 7:58
146  
For every evangelical programmer/blogger there are 1000 avid blog readers that immediately re-invent themselves and adopt the latest techniques. For every one of those there are 10,000 programmers out there with their nose to the grind stone getting a days work done and getting product out the door. Those guys are using tried and trusted techniques that have worked for them for years. They wait until new techniques are widely adopted and show actual benefits before taking them up. Don't call them stupid, and they're anything but lazy, call them "busy" instead. –  Binary Worrier Jun 6 '12 at 12:21
16  
@BinaryWorrier: immutable objects are hardly a "new thing". They might not have been used heavily for domain objects, but Java and C# had them from the very beginning. Also: "lazy" is not always a bad word, some kinds of "lazy" are an absolute advantage for a developer. –  Joachim Sauer Jun 6 '12 at 13:51
10  
@Joachim: I think it's fairly obvious that "lazy" was used in it's pejorative sense above :) Also, Immutable Objects (like Lambda Calculus, and OOP back in the day - yes I am that old) don't need to be new to suddenly become flavour of the month. I'm not arguing that they're a bad thing (they're not), or that they don't have their place (they obviously do), just go easy on folks because they haven't heard the latest Good Word and been converted as fervently oneself (not blaming you for the "lazy" comment, I know you tried to mitigate it). –  Binary Worrier Jun 6 '12 at 14:41
84  
-1, immutable objects arent 'good'. Just more or less appropriate for specific situations. Anyone telling you one technique or another is objectively 'good' or 'bad' over another for all situations is selling you religion. –  GrandmasterB Jun 6 '12 at 20:43

23 Answers 23

up vote 222 down vote accepted

Both mutable and immutable objects have their own uses, pros and cons.

Immutable objects do indeed make life simpler in many cases. They are especially applicable for value types, where objects don't have an identity so they can be easily replaced. And they can make concurrent programming way safer and cleaner (most of the notoriously hard to find concurrency bugs are ultimately caused by mutable state shared between threads). However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious. And for objects with a distinct identity, changing an existing objects is much more simple and intuitive than creating a new, modified copy of it.

Think about a game character. In games, speed is top priority, so representing your game characters with mutable objects will most likely make your game run significantly faster than an alternative implementation where a new copy of the game character is spawned for every little change.

Moreover, our perception of the real world is inevitably based on mutable objects. When you fill up your car with fuel at the gas station, you perceive it as the same object all along (i.e. its identity is maintained while its state is changing) - not as if the old car with an empty tank got replaced with consecutive new car instances having their tank gradually more and more full. So whenever we are modeling some real-world domain in a program, it is usually more straightforward and easier to implement the domain model using mutable objects to represent real-world entities.

Apart from all these legitimate reasons, alas, the most probable cause why people keep creating mutable objects is inertia of mind, a.k.a. resistance to change. Note that most developers of today have been trained well before immutability (and the containing paradigm, functional programming) became "trendy" in their sphere of influence, and don't keep their knowledge up to date about new tools and methods of our trade - in fact, many of us humans positively resist new ideas and processes. "I have been programming like this for nn years and I don't care about the latest stupid fads!"

share|improve this answer
20  
That's right. Especially in GUI programming, mutable object are very handy. –  Florian Salihovic Jun 6 '12 at 7:56
17  
It's not just resistance, I'm sure lots of devs would love to try out the latest and greatest, but how often do new projects spin up in the average dev's environment where they can apply these new practices? Not everone can or will write a hobby project just to try out immutable state. –  Steve Evers Jun 6 '12 at 14:18
19  
Two small caveats to this: (1) Take the moving game character. The Point class in .NET for instance is immutable but creating new points as the result of changes is easy and thus affordable. Animating an immutable character can be made very cheap by decoupling the “moving parts” (but yes, some aspect is then mutable). (2) “large and/or complex objects” can very well be immutable. Strings are often large, and usually benefit from immutability. I once rewrote a complex graph class to be immutable, making the code simpler and more efficient. In such cases, having a mutable builder is the key. –  Konrad Rudolph Jun 6 '12 at 14:23
2  
@SnOrfus, good point, I should add that resistance may come from the organization as well. Luckily, we can always look for a better workplace :-) –  Péter Török Jun 6 '12 at 14:41
3  
@KonradRudolph, good points, thanks. I did not mean to rule out using immutability in complex objects, but implementing such a class correctly and efficiently is far from being a trivial task, and the extra effort required may not be always justified. –  Péter Török Jun 6 '12 at 14:47

I think you've all missed the most obvious answer. Most developers create mutable objects because mutability is the default in imperative languages. Most of us have better things to do with our time than to constantly modify code away from the defaults--more correct or not. And immutability is not a panacea any more than any other approach. It makes some things easier but makes others much more difficult as some answers have already pointed out.

share|improve this answer
7  
In most modern IDEs I know, it takes practically the same amount of effort to generate only getters, as to generate both getters and setters. Although it is true that adding final, const etc. takes a bit of extra effort... unless you set up a code template :-) –  Péter Török Jun 7 '12 at 7:19
2  
@PéterTörök it's not just the additional effort--it's the fact that your fellow coders will want to hang you in effigy because they find your coding style so alien to their experience. That also discourages this sort of thing. –  Onorio Catenacci Jun 7 '12 at 12:37
3  
That might be overcome with more communication and education, e.g. it is advisable to talk or give a presentation to one's teammates about a new coding style before actually introducing it into an existing codebase. It is true that a good project has a common coding style which is not just an amalgam of the coding styles favoured by every (past and present) project member. So introducing or changing coding idioms should be a team decision. –  Péter Török Jun 7 '12 at 13:08
  1. There is a place for mutability. Domain driven design principles provide a solid understanding of what should be mutable and what should be immutable. If you think about it you will realize it is impractical to conceive of a system in which every change of state to an object requires the destruction and re-composition of it, and to every object that referenced it. With complex systems this could easily lead to completely wiping and rebuilding the entire system's object graph

  2. Most developers don't make anything where the performance requirements are significant enough that they need to focus on concurrency (or a lot of other issues that are universally considered good practice by the informed).

  3. There are some things you simply can't do with immutable objects, like have bidirectional relationships. Once you set an association value on one object, it's identity changes. So, you set the new value on the other object and it changes as well. The problem is the first object's reference is no longer valid, because a new instance has been created to represent the object with the reference. Continuing this would just result in infinite regressions. I did a little case study after reading your question, here's what it looks like. Do you have an alternative approach that allows such functionality while maintaining immutability?

        public class ImmutablePerson { 
    
         public ImmutablePerson(string name, ImmutableEventList eventsToAttend)
         {
              this.name = name;
              this.eventsToAttend = eventsToAttend;
         }
         private string name;
         private ImmutableEventList eventsToAttend;
    
         public string Name { get { return this.name; } }
    
         public ImmutablePerson RSVP(ImmutableEvent immutableEvent){
             // the person is RSVPing an event, thus mutating the state 
             // of the eventsToAttend.  so we need a new person with a reference
             // to the new Event
             ImmutableEvent newEvent = immutableEvent.OnRSVPReceived(this);
             ImmutableEventList newEvents = this.eventsToAttend.Add(newEvent));
             var newSelf = new ImmutablePerson(name, newEvents);
             return newSelf;
         }
        }
    
        public class ImmutableEvent { 
         public ImmutableEvent(DateTime when, ImmutablePersonList peopleAttending, ImmutablePersonList peopleNotAttending){
             this.when = when;     
             this.peopleAttending = peopleAttending;
             this.peopleNotAttending = peopleNotAttending;
         }
         private DateTime when; 
         private ImmutablePersonList peopleAttending;
         private ImmutablePersonList peopleNotAttending;
         public ImmutableEvent OnReschedule(DateTime when){
               return new ImmutableEvent(when,peopleAttending,peopleNotAttending);
         }
         //  notice that this will be an infinite loop, because everytime one counterpart
         //  of the bidirectional relationship is added, its containing object changes
         //  meaning it must re construct a different version of itself to 
         //  represent the mutated state, the other one must update its
         //  reference thereby obsoleting the reference of the first object to it, and 
         //  necessitating recursion
         public ImmutableEvent OnRSVPReceived(ImmutablePerson immutablePerson){
               if(this.peopleAttending.Contains(immutablePerson)) return this;
               ImmutablePersonList attending = this.peopleAttending.Add(immutablePerson);
               ImmutablePersonList notAttending = this.peopleNotAttending.Contains( immutablePerson ) 
                                    ? peopleNotAttending.Remove(immutablePerson)
                                    : peopleNotAttending;
               return new ImmutableEvent(when, attending, notAttending);
         }
        }
        public class ImmutablePersonList
        {
          private ImmutablePerson[] immutablePeople;
          public ImmutablePersonList(ImmutablePerson[] immutablePeople){
              this.immutablePeople = immutablePeople;
          }
          public ImmutablePersonList Add(ImmutablePerson newPerson){
              if(this.Contains(newPerson)) return this;
              ImmutablePerson[] newPeople = new ImmutablePerson[immutablePeople.Length];
              for(var i=0;i<immutablePeople.Length;i++)
                  newPeople[i] = this.immutablePeople[i];
              newPeople[immutablePeople.Length] = newPerson;
          }
          public ImmutablePersonList Remove(ImmutablePerson newPerson){
              if(immutablePeople.IndexOf(newPerson) != -1)
              ImmutablePerson[] newPeople = new ImmutablePerson[immutablePeople.Length-2];
              bool hasPassedRemoval = false;
              for(var i=0;i<immutablePeople.Length;i++)
              {
                 hasPassedRemoval = hasPassedRemoval || immutablePeople[i] == newPerson;
                 newPeople[i] = this.immutablePeople[hasPassedRemoval ? i + 1 : i];
              }
              return new ImmutablePersonList(newPeople);
          }
          public bool Contains(ImmutablePerson immutablePerson){ 
             return this.immutablePeople.IndexOf(immutablePerson) != -1;
          } 
        }
        public class ImmutableEventList
        {
          private ImmutableEvent[] immutableEvents;
          public ImmutableEventList(ImmutableEvent[] immutableEvents){
              this.immutableEvents = immutableEvents;
          }
          public ImmutableEventList Add(ImmutableEvent newEvent){
              if(this.Contains(newEvent)) return this;
              ImmutableEvent[] newEvents= new ImmutableEvent[immutableEvents.Length];
              for(var i=0;i<immutableEvents.Length;i++)
                  newEvents[i] = this.immutableEvents[i];
              newEvents[immutableEvents.Length] = newEvent;
          }
          public ImmutableEventList Remove(ImmutableEvent newEvent){
              if(immutableEvents.IndexOf(newEvent) != -1)
              ImmutableEvent[] newEvents = new ImmutableEvent[immutableEvents.Length-2];
              bool hasPassedRemoval = false;
              for(var i=0;i<immutablePeople.Length;i++)
              {
                 hasPassedRemoval = hasPassedRemoval || immutableEvents[i] == newEvent;
                 newEvents[i] = this.immutableEvents[hasPassedRemoval ? i + 1 : i];
              }
              return new ImmutableEventList(newPeople);
          }
          public bool Contains(ImmutableEvent immutableEvent){ 
             return this.immutableEvent.IndexOf(immutableEvent) != -1;
          } 
        }
    
share|improve this answer
1  
+1 for bidirectionality. –  Dan Neely Jun 6 '12 at 22:34
9  
@smartcaveman About (2), I also disagree: in general, a "bidirectional relationship" is a mathematical concept orthogonal to mutability. As usually implemented in Java it does require mutability (I agreed with you on that point). However, I can think of an alternative implementation: a Relationship class between the two objects, with a constructor Relationship(a, b); at the point of creating the relationship, both entities a & b already exist, and the relationship itself is also immutable. I'm not saying this approach is practical in Java; just that it's possible. –  Andres F. Jun 7 '12 at 17:21
1  
@AndresF., So, based on what you're saying, If R is the Relationship(a,b) and both a and b are immutable, neither a nor b would hold a reference to R. For this to work, the reference would have to be stored somewhere else (like a static class). Am I understanding your intention correctly? –  smartcaveman Jun 7 '12 at 18:38
4  
It is possible to store a bidirectional relationship for immutable data as Chthulhu points out via laziness. Here is one way to do this: haskell.org/haskellwiki/Tying_the_Knot –  Thomas Eding Aug 24 '12 at 23:36

I've been reading "purely functional data structures", and it's made me realize that there are quite a few data structures that are much easier to implement using mutable objects.

To implement a binary search tree, you have to return a new tree every time: Your new tree will have had to make a copy of each node that has been modified (the un-modified branches are shared). For your insert function this isn't too bad, but for me, things got fairly inefficient quickly when I started to work on delete and re-balance.

The other thing to realize is that you can go years writing object oriented code, and never really realize how terrible shared mutable state can be, if your code isn't run in a way that will expose concurrency problems.

share|improve this answer
3  
Is this the Okasaki book? –  Mechanical snail Jun 7 '12 at 3:01
3  
Funny, I always thought Okasakis red/black tree was so much simpler. 10 lines or so. I guess the biggest advantage is when you actually want to keep the old version around as well. –  Thomas Ahle Jun 15 '12 at 13:43

From my point of view, that's a lack of awareness. If you look at other known JVM languages (Scala, Clojure), mutable objects are seen rarely in the code and that's why people start using them in scenarios where single threading is not enough.

I'm currently learning Clojure and have a little experience in Scala (4 years + in Java as well) and your coding style changes because of the awareness of state.

share|improve this answer
2  
+1: I agree: after learning some Scala and Haskell, I tend to use final in Java and const in C++ everywhere. I also use immutable objects if possible and, while mutable objects are still needed very often, it is amazing how often you can use immutable ones. –  Giorgio Aug 17 '12 at 16:19

Why do people keep killing themselves, or smoking cigarettes, or using Java at all? Why did previous generations believe the Earth is flat, and go on giant Crusades to eradicate everyone who didn't share their religion? Why do some people go on killing sprees? Why do some people refuse to believe in unintuitive science, like quantum mechanics, even though the entire world around them is built on devices that function because of these principles?

Your question is based on a fundamentally faulty premise- that "people" must do things for some reason, and that reason must be logical. This is a variant of the appeal to authority fallacy.

The only way to discover why a specific person does anything is to ask them. Even then, there is no guarantee at all that the answer is useful or meaningful in the slightest.

share|improve this answer
12  
It's highly inaccurate to state that previous generations believed the Earth was flat or that the Crusades were about wiping out everyone who did not share the Crusaders' religion. These ideas may be familiar artifacts of pop culture, but we ought to hold ourselves to a higher standard, particularly on a site dedicated specifically to the dissemination of accurate knowledge. –  Mason Wheeler Jun 6 '12 at 23:21
4  
@MasonWheeler: Does that even matter? If anything, it even reinforces my point. –  DeadMG Jun 7 '12 at 0:51
6  
Why do people keep killing themselves, or smoking cigarettes, or using C++ at all? –  Giorgio Aug 17 '12 at 16:00
2  
@Thomas Eding: Java is an amazing language too and nobody asked for an answer beginning with a rant against Java. I thought rants do not belong in this site but they keep showing up again and again. –  Giorgio Sep 20 '12 at 5:41

I think one major contributing factor has been ignored: Java Beans rely heavily on a specific style of mutating objects, and (especially considering the source) quite a few people seem to take that as a (or even the) canonical example of how all Java should be written.

share|improve this answer
3  
+1, the getter/setter pattern is used way too often as some sort of default implementation after the first data analysis. –  Jaap Jun 7 '12 at 12:12

Every enterprise Java system that I've worked on in my career uses either Hibernate or the Java Persistence API (JPA). Hibernate and JPA essentially dictate that your system uses mutable objects, because the whole premise of them is that they detect and save changes to your data objects. For many projects the ease of development that Hibernate brings is more compelling than the benefits of immutable objects.

Obviously mutable objects have been around for much longer than Hibernate, so Hibernate is probably not the original 'cause' of the popularity of mutable objects. Maybe the popularity of mutable objects allowed Hibernate to flourish.

But today if many junior programmers cut their teeth on enterprise systems using Hibernate or another ORM then presumably they'll pick up the habit of using mutable objects. Frameworks like Hibernate may be entrenching the popularity of mutable objects.

share|improve this answer

A major point not yet mentioned is that having the state of an object be mutable makes it possible to have the identity of the object which encapsulates that state be immutable.

Many programs are designed to model real-world things which are inherently mutable. Suppose that at 12:51am, some variable AllTrucks holds a reference to object #451, which is the root of a data structure which indicates what cargo is contained in all the trucks of a fleet at that moment (12:51am), and some variable BobsTruck can be used to get a reference to object #24601 points to an object which indicates what cargo is contained in Bob's truck at that moment (12:51am). At 12:52am, some trucks (including Bob's) are loaded and unloaded, and data structures are updated so that AllTrucks will now hold a reference to a data structure which indicates the cargo is in all the trucks as of 12:52am.

What should happen to BobsTruck?

If the 'cargo' property of each truck object is immutable, then object #24601 will forevermore represent the state that Bob's truck had at 12:51am. If BobsTruck holds a direct reference to object #24601, then unless the code which updates AllTrucks also happens to update BobsTruck, it will cease to represent the current state of Bob's truck. Note further that unless BobsTruck is stored in some form of mutable object, the only way that the code which updates AllTrucks could update it would be if the code was explicitly programmed to do so.

If one wants to be able to use BobsTruck to observe the state Bob's truck while still keeping all objects immutable, one could have BobsTruck be an immutable function which, given the value that AllTrucks has or had at any particular time, will yield the state of Bob's truck at that time. One could even have it hold a pair of immutable functions--one of which would be as above, and the other of which would accept a reference to a fleet state and a new truck state, and return a reference to a new fleet state which matched the old, except that Bob's truck would have the new state.

Unfortunately, having to use such a function every time one wants to access the state of Bob's truck could get rather annoying and cumbersome. An alternative approach would be to say that object #24601 will always and forevermore (as long as anyone holds a reference to it) represent the current state of Bob's truck. Code which will want to repeatedly access the current state of Bob's truck wouldn't have to run some time-consuming function every time--it could simply do a lookup function once to find out that object #24601 is Bob's truck, and then simply access that object any time it wants to see the present state of Bob's truck.

Note that the functional approach is not without advantages in a single-threaded environment, or in a multi-threaded environment where threads will mostly just be observing data rather than changing it. Any observer thread which copies the object reference contained in AllTrucks and then examines the truck states represented thereby will see the state of all the trucks as of the moment that it grabbed the reference. Any time an observer thread wants to see newer data, it can just re-grab the reference. On the other hand, having the entire state of the fleet represented by a single immutable object would preclude the possibility of two threads updating different trucks simultaneously, since each thread if left to its own devices would produce a new "fleet state" object which included the new state of its truck and the old states of every other. Correctness may be assured if each each thread uses CompareExchange to update AllTrucks only if it hasn't changed, and responds to a failed CompareExchange by regenerating its state object and retrying the operation, but if more than one thread attempts a simultaneous write operation, performance will generally be worse than if all writing were done on a single thread; the more threads attempt such simultaneous operations, the worse the performance will get.

If individual truck objects are mutable but have immutable identities, the multi-threaded scenario becomes cleaner. Only one thread may be allowed to operate at a time on any given truck, but threads operating on different trucks could do so without interference. While there are ways one could emulate such behavior even when using immutable objects (e.g. one could define the "AllTrucks" objects so that setting state of truck belonging to XXX to SSS would simply require generating an object that said "As of [Time], the state of the truck belonging to [XXX] is now [SSS]; the state of everything else is [Old value of AllTrucks]". Generating such an object would be fast enough that even in the presence of contention, a CompareExchange loop wouldn't take long. On the other hand, using such a data structure would substantially increase the amount of time required to find a particular person's truck. Using mutable objects with immutable identities avoids that problem.

share|improve this answer

There's no right or wrong, it just depends what you prefer. There's a reason why some people prefer languages that favor one paradigm over another, and one data model over another. It just depends on your preference, and on what you want to achieve (and being able to easily use both approaches without alienating die-hard fans of one side or another is a holy grail some languages are seeking after).

I think the best and quickest way to answer your question is for you to head over Pros and Cons of Immutability vs Mutability.

share|improve this answer

Why do people use any powerful feature? Why do people use meta-programming, laziness or dynamic typing? The answer is convenience. Mutable state is so easy. It's so easy to update in place and the threshold of project size where immutable state is more productive to work with than mutable state is quite high so the choice won't bite you back for a while.

share|improve this answer

Programming languages are designed for execution by computers. All important building blocks of computers - CPU's, RAM, cache, disks - are mutable. When they aren't (BIOS), they're really immutable and you can't create new immutable objects either.

Hence, any programming language built on top of immutable objects suffers from a representation gap in its implementation. And for early languages such as C, that was a big stumbling block.

share|improve this answer

In Java immutable objects require a constructor that will take all the properties of the object (or the constructor creates them from other arguments or defaults). Those properties should be marked final.

There are four problems with this mostly having to do with data binding:

  1. Java Constructors reflection meta-data does not retain the argument names.
  2. Java Constructors (and methods) do not have named parameters (also called labels) thus it gets confusing with many parameters.
  3. When inheriting another immutable object proper order of constructors must be called. This can be rather tricky to the point of just giving up and leaving one of the fields non-final.
  4. Most binding technologies (like Spring MVC Data Binding, Hibernate, etc...) will only work with no-arg default constructors (this was because annotations did not always exist).

You can mitigate #1 and #2 using annotations like @ConstructorProperties and creating another mutable builder object (usually fluent) to create the immutable object.

share|improve this answer

Im surprised that no one has mentioned the performance optimization benefits. Depending on the language a compiler can make a bunch of optimizations when dealing with immutable data because it knows the data will never change. All sorts of stuff is skipped over, which gives you tremendous performance benefits.

Also immutable objects almost eliminate the entire class of state bugs.

Its not as big as it should be because its harder, doesn't apply to every language and most people were taught imperative coding.

Also i have found that most programmers are happy in their box and are often resistant to new ideas that they don't completely understand. In general people dont like change.

Also remember, that the state of most programmers is bad. Most programming that is done in the wild is terrible and its caused by a lack of understanding and politics.

share|improve this answer

Without mutable objects you have no state. Admittedly, this is a good thing if you can manage it and if there is any chance an object might be referenced from more than one thread. But the program is going to be rather boring. A lot of software, particularly web servers, avoids taking responsibility for mutable objects by pushing mutability off on databases, operating systems, system libraries, etc. As a practical matter, this does free the programmer from mutability problems and makes web (and other) development affordable. But the mutability is still there.

In general, you have three types of classes: normal, non-thread-safe classes, that have to be carefully guarded and protected; immutable classes, which can be used freely; and mutable, thread-safe classes that can be used freely but which must be written with extreme care. The first type is the troublesome one, with the worst ones being those that are thought to be of the third type. Of course, the first type are the easy ones to write.

I usually end up with lots of normal, mutable classes that I have to watch very carefully. In a multi-thread situation, the synchronization necessary slows everything down even when I can avoid a deadly embrace. So I'm ususally making immutable copies of the mutable class and handing those off to whoever can use it. A new immutable copy is needed every time the orignal mutates, so I imagine at times I may have a hundred copies of the original out there. I'm utterly dependent on Garbage Collection.

In summary, non-thread-safe, mutable objects are fine if you are not using multiple threads. (But multithreading is inflitrating everywhere--be careful!) They can be used safely otherwise if you restrict them to local variables or rigorously synchronize them. If you can avoid them by using other people's proven code (DBs, system calls, etc.) do so. If you can use an immutable class, do so. And I think, in general, people are either unaware of multithreading problems or are (sensibly) terrified of them and using all kinds of tricks to avoid multithreading (or rather, pushing responsibility for it elsewhere).

As a P.S., I sense that Java getters and setters are getting out of hand. Check this out.

share|improve this answer
5  
Immutable state is still state. –  Jeremy Heiler Jun 6 '12 at 22:01
3  
@JeremyHeiler: True, but it's the state of something that is mutable. If nothing mutates, there is only one state, which is the same thing as no state at all. –  RalphChapin Jun 7 '12 at 20:07

Lots of people had good answers so I want to point out something you touched on that was very observant and extremely true and hasn't been mentioned elsewhere here.

Automatically creating setters and getters is a horrible, horrible idea, yet it's the first way procedural-minded people try to force OO into their mindset. Setters and getters, along with properties should only be created when you find you need them and not everyby default

In fact although you need getters pretty regularly, the only way setters or writable properties should ever exist in your code is through a builder pattern where they are locked down after the object has been completely instantiated.

Many classes are mutable after creation which is fine, it just shouldn't have it's properties directly manipulated--instead it should be asked to manipulate it's properties through method calls with actual business logic in them (Yes, a setter is pretty much the same thing as directly manipulating the property)

Now this doesn't really apply to "Scripting" style code/languages either but to code you create for someone else and expect others to read repeatedly over the years. I've had to start making that distinction lately because I enjoy messing with Groovy so much and there is a huge difference in targets.

share|improve this answer

Mutable objects are used when you have to set multiples values after instantiating the object.

You shouldn't have a constructor with, say, six parameters. Instead you modify the object with setter methods.

An example of this is a Report object, with setters for font, orientation etc.

For short: mutables are useful when you have a lot of state to set to an object and it would not be practical to have a very long constructor signature.

EDIT: Builder pattern can be used build the whole state of the object.

share|improve this answer

I think using mutable objects stems from imperative thinking: you compute a result by changing the content of mutable variables step by step (computation by side effect).

If you think functionally, you want to have immutable state and represent subsequent states of a system by applying functions and creating new values from old ones.

The functional approach can be cleaner and more robust, but it can be very inefficient because of copying, so that you want to fall back to a shared data structure that you modify incrementally.

The trade-off that I find most reasonable is: Start with immutable objects and then switch to mutable ones if your implementation is not fast enough. From this point of view, using mutable objects systematically from the beginning can be considered some kind of premature optimization: you choose the more efficient (but also more difficult to understand and to debug) implementation from the beginning.

So, why do many programmers use mutable objects? IMHO for two reasons:

  1. Many programers have learnt how to program using an imperative (procedural or object-oriented) paradigm, therefore mutability is their basic approach to defining computation, i.e. they do not know when and how to use immutability because they are not familiar with it.
  2. Many programmers worry about performance too early whereas it is often more effective to first focus on writing a program that is functionally correct, and then try to find bottlenecks and optimize it.
share|improve this answer
1  
I am not a FP expert but AFAIK (1) thread communication can be achieved by creating an immutable value in one thread and reading it in another (again, AFAIK, this is the Erlang approach) (2) AFAIK the notation for setting a property does not change much (e.g. in Haskell setProperty record value corresponds to Java record.setProperty(value)), only the semantics changes because the result of setting a property is a new immutable record. –  Giorgio Aug 22 '12 at 23:07
1  
"both must have a reference to a shared object which one can put data and the other can read it": more precisely, you can make an object immutable (all members const in C++ or final in Java) and set all the content in the constructor. Then this immutable object is handed-over from the producer thread to the consumer thread. –  Giorgio Aug 22 '12 at 23:12
1  
(2) I have already listed performance as a reason not to use immutable state. Regarding (1), of course the mechanism that implements the communication between threads needs some mutable state, but you can hide this from your programming model, see e.g. the actor model (en.wikipedia.org/wiki/Actor_model). So even if at a lower level you need mutability to implement the communication, you can have an upper abstraction level in which you communicate between threads sending immutable objects back and forth. –  Giorgio Aug 22 '12 at 23:21
1  
I am not sure I understand you fully, but even a pure functional language where every value is immutable, there is one mutable thing: the program state, i.e. the current program stack and variable bindings. But this is the execution environment. Anyway, I suggest that we discuss this in chat some time and then clean up the messages from this question. –  Giorgio Aug 23 '12 at 16:04

I know you are asking about Java, but I use mutable vs immutable all the time in objective-c. There is a immutable array NSArray, and a mutable array NSMutableArray. These are two different classes written specifically in an optimized way to handle the exact use. If I need to create an array and never alter it's contents, I'd use NSArray, which is a smaller object and is much faster at what it does, compared to a mutable array.

So if you create a Person object that is immutable then you only need a constructor and getters, thus the object will be smaller and use less memory, which in turn will make your program actually faster. If you need to change the object after creation then a mutable Person object will be better so that it can change the values instead of creating a new object.

So: depending on what you plan on doing with the object, choosing mutable vs immutable can make a huge difference, when it comes to performance.

share|improve this answer

Immutable means you can't change the value, and mutable means you can change the value if you think in terms of primitives, and objects. Objects are different than primitives in Java in that they are built in types. Primitives are built in types like int, boolean, and void.

A lot of people people think that primitives and objects variables that have a final modifier infront of them are immutable, however, this isn't exactly true. So final almost doesn't mean immutable for variables. Check out this link for a code sample:

public abstract class FinalBase {

    private final int variable; // Unset

    /* if final really means immutable than
     * I shouldn't be able to set the variable
     * but I can.
     */
    public FinalBase(int variable) { 
        this.variable = variable;
    }

    public int getVariable() {
        return variable;
    }

    public abstract void method();
}

// This is not fully necessary for this example
// but helps you see how to set the final value 
// in a sub class.
public class FinalSubclass extends FinalBase {

    public FinalSubclass(int variable) {
        super(variable);
    }

    @Override
    public void method() {
        System.out.println( getVariable() );
    }

    @Override
    public int getVariable() {

        return super.getVariable();
    }

    public static void main(String[] args) {
        FinalSubclass subclass = new FinalSubclass(10);
        subclass.method();
    }
}
share|improve this answer

Check this blog post: http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html. It summarizes why immutable objects are better than mutable. Here is a short list of arguments:

  • immutable objects are simpler to construct, test, and use
  • truly immutable objects are always thread-safe
  • they help to avoid temporal coupling
  • their usage is side-effect free (no defensive copies)
  • identity mutability problem is avoided
  • they always have failure atomicity
  • they are much easier to cache

People are using mutable objects, as far as I understand, because they are still mixing OOP with imperative procedural programming.

share|improve this answer

I think a good reason would be to model "real-life" mutable "objects", like interface windows. I vaguely remember having read that the OOP was invented when somebody tried to write software to control some cargo port operation.

share|improve this answer
1  
I cannot find yet where i've read this about the origins of OOP, but according to Wikipedia, some Integrated Regional Information System of a large container shipping company OOCL is written in Smalltalk. –  Alexey Jan 1 at 9:55

Java, in many cases mandates mutable objects, eg when you want to count or return something in a visitor or runnable, you need final variables, even without multithreading.

share|improve this answer
5  
final is actually about 1/4 of a step towards immutability. Not seeing why you mention it. –  cHao Jun 7 '12 at 4:11
1  
There are actually very few cases where a mutable object is required. There are cases where the code would be clearer, or in some cases faster, by using mutable objects. But consider that the vast majority of design patterns are basically just a half-assed rendition of functional programming for languages that don't natively support it. Fun part of that is, FP only requires mutability in very select places (namely, where side effects must occur), and those places are generally tightly limited in number, size, and scope. –  cHao Dec 27 '12 at 15:32

protected by Doc Brown Mar 17 at 21:17

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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