Downsides to immutable objects in Java? [closed]

2019-01-21 13:33发布

The advantages of immutable objects in Java seem clear:

  • consistent state
  • automatic thread safety
  • simplicity

You can favour immutability by using private final fields and constructor injection.

But, what are the downsides to favouring immutable objects in Java?

i.e.

  • incompatibility with ORM or web presentation tools?
  • Inflexible design?
  • Implementation complexities?

Is it possible to design a large-scale system (deep object graph) that predominately uses immutable objects?

17条回答
三岁会撩人
2楼-- · 2019-01-21 13:43

Immutability, as every other design pattern, should only be used when you need it. You give the example of thread safety: In a highly threaded application, you could favor immutability over the added expense of making it thread safe yourself. However, if your design requires objects to be mutable, don't go out of your way to make them immutable, just because "it's a design pattern".

As for your graph, you could choose to make your nodes immutable and let another class take care of the connections between them, or you could make a mutable node that takes care of its own children and has an immutable value class.

查看更多
3楼-- · 2019-01-21 13:44

The problem in java is that one has to live with all those objects, where the class looks like:

class Mutable {
    State1 f1;
    MoreState f2;
    void doSomething() {  // mutate the state, but don't document it }
    void doSomethingElse()  /// mutate the state heavily, do not mention in doc
}  

(Note the missing Cloneable interface).

The problem with the garbage collector is not such a big one nowadays. The VM's are happy with short living objects.

Advances in Compiler/JIT technology will make it possible, sooner or later, to optimize intermediate temporary object creation away. For example:

BigInteger  three =, two =, i1 = ...;
BigInteger  i2 = i1.mul(three).div(two);  

The JIT could notice that the intermediate object i1.mul(three) can be used for the end result and call a variant of the div method that works on a mutable accumulator.

查看更多
Lonely孤独者°
4楼-- · 2019-01-21 13:47

The answer is none. There are not any good reasons to be mutable.

You do run in to problems with lots of frameworks(or framework versions) that require mutable objects in order to work with them(Spring I am glaring in your direction). As you work with them and fish through the code you will shake your fist in anger that you need to introduce dirty mutability into an otherwise glorious block of code when it could have been easily avoided.

I'm sure there are limited corner cases(probably more hypothetical that anything) where the overhead of object creation and collection is uncceptable. But I urge the people that would make this argument to look at languages like scala where included collections are immutable by default and then look at the bevy of performance critical apps built on top of that concept.

This is of course hyperbole. In reality, you should go with immutability first, see if it causes you any measurable problems, if it does then introduce mutability, but make sure you can prove it solves your problem. Otherwise you've just created liability for no benefit. In doing this I think you'll find objective cases for "Implementation Complexity" and "Inflexibility" very hard to make.

查看更多
叛逆
5楼-- · 2019-01-21 13:51

In Java, a method can't return multiple objects, like return a, b, c. Returning an array of objects makes the code look ugly. In this situation, I have to pass mutable objects to the method and let it change the states of these objects. However, I don't know whether returning multiple objects is a code smell or not.

查看更多
Juvenile、少年°
6楼-- · 2019-01-21 13:54

You pretty much answered your own question. The JavaBean specification, I don't believe, mentions anything about immutability, yet JavaBeans are the bread and butter of many Java frameworks.

查看更多
我想做一个坏孩纸
7楼-- · 2019-01-21 13:54

Some implementations of immutable objects have transactional means to update an immutable object. Similar to how databases provide safe commits and rollbacks. But in apparent contrast with many of the answers here. Immutable objects are never changed. A typical operation would be.

B = append(A,C)

B is a new object. Just like A and C. No modification was made to A or C. Internally a red black tree implementation makes such semantics fast enough to be usable.

The downside is that it is not as fast as making the operations in place. But that only compares a single part of the system. When evaluating possible downsides we need to look at the system as a whole. And I personally don't have a clear picture of the entire impact. Although I suspect immutability wins out at the end.

I know some experts contend there is contention at the top level of the red black tree. And that has a negative effect in throught-put.

查看更多
登录 后发表回答