Is Boolean imutable?

IsBoolean imutable? I don't see any way to change the boolean value of aBoolean object without changing the reference.

Ideally I'd like to keep the same object reference, and change the boolean value of aBoolean object. I could wrap it, but that would mean a lot of rewrite. Does anyone know of a way to change the boolean value of aBoolean object?

As a side note, ifBooleans ARE imutable, why are there public constructors forBoolean? Why not two staticBoolean instances (as there are, TRUE and FALSE) and have a factory meathod return either of these? In essence, making theBoolean class similar to the "type safe enumeration" meathod.

Jeremy Jenkins

[757 byte] By [blowz] at [2007-9-26 3:59:27]
# 1
Boolean (as well as other Objects that wrap primitives) are immutable.There are two static instances...Boolean.TRUEBoolean.FALSECheck out http://java.sun.com/j2se/1.3/docs/api/java/lang/Boolean.html
alee1010 at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 2

Actually, if you look at the documentation for the hashCode() method, you'll see that hashCode is defined to return one of two known values, depending on whether the value of the Boolean object is TRUE or FALSE.

This would seem to imply to me that there are only two Boolean objects, and the Boolean constructor simply passes a reference to one of them when you instantiate a Boolean ...

Larry

ldadams at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 3

> Actually, if you look at the documentation for the

> hashCode() method, you'll see that hashCode is defined

> to return one of two known values, depending on

> whether the value of the Boolean object is TRUE or

> FALSE.

>

> This would seem to imply to me that there are only two

> Boolean objects, and the Boolean constructor simply

> passes a reference to one of them when you instantiate

> a Boolean ...

That's what I was thinking. I tried the simple test...

[code]

Boolean b = new Boolean(true);

Boolean bb = new Boolean(true);

boolean test = (b == bb);

System.out.println("b == bb is " + test);

[\code]

and the resulting output was false. This made me think the Boolean constructor was creating a new instance for every constructed Boolean object. Seems it would make more sense to do as you had said... return one of the static TRUE/FALSE instances instead of constructing a brand new Boolean.

blowz at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 4

Well, I think it does in fact work the way we suspect...

Boolean bTrue1 = new Boolean ("true");

Boolean bTrue2 = new Boolean ("true");

Boolean bFalse = new Boolean ("false");

System.out.println ("bTrue1: " + bTrue1 + " (" + bTrue1.hashCode() + ")");

System.out.println ("bTrue2: " + bTrue2 + " (" + bTrue2.hashCode() + ")");

System.out.println ("bFalse: " + bFalse + " (" + bFalse.hashCode() + ")");

System.out.println ("bTrue1.equals (bTrue2) == " + bTrue1.equals (bTrue2));

System.out.println ("bTrue2.equals (bTrue1) == " + bTrue2.equals (bTrue1));

System.out.println ("bTrue1.equals (bFalse) == " + bTrue1.equals (bFalse));

System.out.println ("bFalse.equals (bTrue1) == " + bFalse.equals (bTrue1));

System.out.println ("bTrue2.equals (bFalse) == " + bTrue2.equals (bFalse));

System.out.println ("bFalse.equals (bTrue2) == " + bFalse.equals (bTrue2));

which, for me, returns the following:

bTrue1: true (1231)

bTrue2: true (1231)

bFalse: false (1237)

bTrue1.equals (bTrue2) == true

bTrue2.equals (bTrue1) == true

bTrue1.equals (bFalse) == false

bFalse.equals (bTrue1) == false

bTrue2.equals (bFalse) == false

bFalse.equals (bTrue2) == false

Also, if I use the constructor that takes a boolean argument, I get the same results...

Larry

ldadams at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 5

blowz seems to have it right. I tried

Boolean b1 = new Boolean(true);

Boolean b2 = new Boolean(true);

System.out.println("b1 == b2 is " + (b1 == b2));

System.out.println("b1 == Boolean.TRUE is " + (b1 == Boolean.TRUE));

The output was:

b1 == b2 is false

b1 == Boolean.TRUE is false

The same "value", (the value depends on the way hashCode is written/overridden), will always hash to the same hashCode. This does not mean they are the same instance.

alee1010 at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 6

> bTrue1: true (1231)

> bTrue2: true (1231)

> bFalse: false (1237)

> bTrue1.equals (bTrue2) == true

> bTrue2.equals (bTrue1) == true

> bTrue1.equals (bFalse) == false

> bFalse.equals (bTrue1) == false

> bTrue2.equals (bFalse) == false

> bFalse.equals (bTrue2) == false

But these cases test for logical equality though. If bTrue1 and bTrue2 were the same object, then:

bTrue1 == bTrue2

would return true; it returns false. I suspect they did it this way to keep construction consistent with the other primitive wrappers.

blowz at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 7
ahh.. my mistake.weren't we debating, though, whether the Boolean constructor returns a reference to one of two known Boolean objects? Not whether your Boolean object is one of those two, but whether it refers to one of those two!
ldadams at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 8

> weren't we debating, though, whether the Boolean

> constructor returns a reference to one of two known

> Boolean objects?

I'm not sure this would be possible. To have a constructor return a class field. I believe this would require a factory method to return either TRUE or FALSE and make the constructor private.

> Not whether your Boolean object is one of those

> two, but whether it refers to one of those

> two!

Hhmmmmm... I may be confused by your meaning of is and refers.

Boolean b1 = Boolean.TRUE;

Boolean b2 = Boolean.TRUE;

Boolean b3 = new Boolean(true);

I would say:

b1 and b2 both refer to the same object, but also, b1 is b2. both references are identical. However, b2 and b3 do not refer to the same object, and therefore aren't the same object, though they are logically equal.

blowz at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 9
[[ Hhmmmmm... I may be confused by your meaning of is and refers. ]]So it really does depend on "what the meaning of is is".Rich
rmiller1985 at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 10

why, certainly! in some jurisdictions, i'm sure, it's the difference between pandering and umm, well...

in any case...

Boolean b1 = Boolean.TRUE;

Boolean b2 = Boolean.TRUE;

Boolean b3 = new Boolean (true);

System.out.println ("b1.hashCode() = " + b1.hashCode());

System.out.println ("b2.hashCode() = " + b2.hashCode());

System.out.println ("b3.hashCode() = " + b3.hashCode());

System.out.println ("b1.equals(b2) = " + b1.equals(b2));

System.out.println ("b1.equals(b3) = " + b1.equals(b3));

System.out.println ("b1 == b2is" + (b1 == b2));

System.out.println ("b1 == b3is" + (b1 == b3));

returns

b1.hashCode() = 1231

b2.hashCode() = 1231

b3.hashCode() = 1231

b1.equals(b2) = true

b1.equals(b3) = true

b1 == b2istrue

b1 == b3isfalse

so, b1.equals(b2) ... and b2.equals(b3). that is, their objects are equivalent.

in addition, b1, b2, and b3 all refer to the same object (the static Boolean.TRUE).

of course, b1 and b3 are distinct objects, b2 and b3 are distinct objects, but b1 and b2 are the same object. why? well, b1 and b2 are both set to Boolean.TRUE -- the same object. b3's value is equivalent to Boolean.TRUE's value, but they're not the same object.

questions...?

why b1 and b2 are the same object, though... hmm

ldadams at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 11
oops, sorry... that last line was some bleed-through, before I thoroughly thought through my answer!
ldadams at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 12

That's what we've been saying...

Previously, you stated "Well, I think it does in fact work the way we suspect..." referring to "This would seem to imply to me that there are only two Boolean objects, and the Boolean constructor simply passes a reference to one of them when you instantiate a Boolean ...". You've show this false through your code example, so you agree with us :)

I was just pointing out hashCode doesn't tell you whether references are the same, it tells you the value (in most cases, excluding collisions) is the same.

alee1010 at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...
# 13

But what do you want to compare? The object Boolean or the value.

Because then it is needed to use the method booleanValue() and then all makes sense:

Boolean b1=new Boolean(true);

Boolean b2=new Boolean(true);

System.out.println("b1 "+b1.booleanValue());

System.out.println("b2 "+b2.booleanValue());

boolean comp=(b2.booleanValue()==Boolean.TRUE.booleanValue())?true:false;

System.out.println("b1 with TRUE "+comp);

The result is:

b1 true

b2 true

b1 with TRUE true

Well, I don't know if it helps

Maria

mmariab at 2007-6-29 12:53:30 > top of Java-index,Archived Forums,Java Programming...