Why Wrapper class like Boolean in java is immutable?

10,005

Solution 1

Because 2 is 2. It won't be 3 tomorrow.

Immutable is always preferred as the default, especially in multithreaded situations, and it makes for easier to read and more maintainable code. Case in point: the Java Date API, which is riddled with design flaws. If Date were immutable the API would be very streamlined. I would know Date operations would create new dates and would never have to look for APIs that modify them.

Read Concurrency in Practice to understand the true importance of immutable types.

But also note that if for some reason you want mutable types, use AtomicInteger AtomicBoolean, etc. Why Atomic? Because by introducing mutability you introduced a need for threadsafety. Which you wouldn't have needed if your types stayed immutable, so in using mutable types you also must pay the price of thinking about threadsafety and using types from the concurrent package. Welcome to the wonderful world of concurrent programming.

Also, for Boolean - I challenge you to name a single operation that you might want to perform that cares whether Boolean is mutable. set to true? Use myBool = true. That is a re-assignment, not a mutation. Negate? myBool = !myBool. Same rule. Note that immutability is a feature, not a constraint, so if you can offer it, you should - and in these cases, of course you can.

Note this applies to other types as well. The most subtle thing with integers is count++, but that is just count = count + 1, unless you care about getting the value atomically... in which case use the mutable AtomicInteger.

Solution 2

Wrapper classes in Java are immutable so the runtime can have only two Boolean objects - one for true, one for false - and every variable is a reference to one of those two. And since they can never be changed, you know they'll never be pulled out from under you. Not only does this save memory, it makes your code easier to reason about - since the wrapper classes you're passing around you know will never have their value change, they won't suddenly jump to a new value because they're accidentally a reference to the same value elsewhere.

Similarly, Integer has a cache of all signed byte values - -128 to 127 - so the runtime doesn't have to have extra instances of those common Integer values.

Solution 3

Patashu is the closest. Many of the goofy design choices in Java were because of the limitations of how they implemented a VM. I think originally they tried to make a VM for C or C++ but it was too hard (impossible?) so made this other, similar language. Write one, run everywhere! Any computer sciency justification like those other dudes spout is just after-the-fact folderal. As you now know, Java and C# are evolving to be as powerful as C. Sure, they were cleaner. Ought to be for languages designed decade(s) later! Simple trick is to make a "holder" class. Or use a closure nowadays! Maybe Java is evolving into JavaScript. LOL.

Share:
10,005
Avinash Singh
Author by

Avinash Singh

Updated on July 06, 2022

Comments

  • Avinash Singh
    Avinash Singh almost 2 years

    I can't see the reason why the Boolean wrapper classes were made Immutable.

    Why the Boolean Wrapper was not implemented like MutableBoolean in Commons lang which actually can be reset.

    Does anyone have any idea/understanding about this ? Thanks.

  • Avinash Singh
    Avinash Singh about 11 years
    When I am programming , I am not defining a 2 , I am defining a variable which holds a value like 2 , and in this case it is a reference so I should be able to change it to a new value.
  • djechlin
    djechlin about 11 years
    @AvinashSingh So do it! Integer count = 2; /* ... */; count = 3; is perfectly legal. And 2 and 3 never have to change and your use case is met.
  • Avinash Singh
    Avinash Singh about 11 years
    I understand the reason that it should have only either TRUE or false value but why does the reference gets reinitialized when I change Boolean b = Boolean.TRUE;
  • Patashu
    Patashu about 11 years
    @Avinash Singh The semantics of the = operator on a reference type (any non-primitive) in Java is to change the reference held by the variable to the reference of the newly assigned object.
  • Avinash Singh
    Avinash Singh about 11 years
    If I change Boolean b = Boolean.TRUE and then I pass the it to another method say hello(Boolean b1){b1 = Boolean.FALSE} then it doesn't change value of b . It makes it difficult to pass the Boolean value between the pages , say from a JSF page to an Action which resets a button display
  • djechlin
    djechlin about 11 years
    @AvinashSingh that is a legitimate tradeoff and in programming in Java you have to get used to it and structure your programs to avoid this use case, although in my opinion it's consistent with good OO design. Object Foo shouldn't be passing its bool to be modified; it should expose a method to modify it. Using AtomicBoolean can be a workaround but it's potentially an anti-pattern you'd rather design around needing than code around.
  • Avinash Singh
    Avinash Singh about 11 years
    Yes I understand that but why it doesn't allow changing the value the Boolean object holds , why it doesn't allow something like 'new Boolean().setValue(false)';
  • dsh
    dsh about 11 years
    This is almost correct. Unfortunately, Boolean, and Integer, have public constructors. So I can write new Boolean(true) and allocate a new instance on the heap. Likewise new Integer(1). Tip: don't use new on these classes and let the compiler optimize away the extraneous memory use. Also, don't test for identity when you really want equality!
  • Avinash Singh
    Avinash Singh about 11 years
    I have used MutableBoolean from commons lang before . I guess my question is why Boolean class was not created like AtomicBoolean. I guess it has to do with memory ?? Thanks for your help.
  • djechlin
    djechlin about 11 years
    @AvinashSingh No, it has to do with 1) good OO design and 2) concurrency, as explained in my answer. Or rather, those are the modern reasons for it, I don't know the history.
  • Louis Wasserman
    Louis Wasserman about 11 years
    Here's another example. Suppose you could change the value of a Boolean. Now you can't just return Boolean.TRUE from a method -- you have to return new Boolean(true). Now you have to waste lots and lots of memory creating a new Boolean every time you want to wrap a primitive boolean in an object. If you just returned Boolean.TRUE, someone could do TRUE.setValue(false) and suddenly true is false and right is wrong and if you're lucky your program will fail with a useful error message instead of firing off nuclear missiles.
  • djechlin
    djechlin about 11 years
    @LouisWasserman IIRC since Java 7 Right and Wrong are no longer implemented using Boolean so you should be fine in this case.
  • TimJowers2
    TimJowers2 about 9 years
    BTW, the reason I think "originally they tried to make a VM for C or C++" is because of a PPT I recall from Sun IIRC from the mid-1990's which all but stated that.