wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Explain the strange behavior of Boolean Class?? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Explain the strange behavior of Boolean Class??" Watch "Explain the strange behavior of Boolean Class??" New topic
Author

Explain the strange behavior of Boolean Class??

ganesh subbiah
Ranch Hand

Joined: Nov 18, 2004
Posts: 39
I have doubt in this code given below .

public class Kirving{
public static void main(String argv[])
{
String s1= new String("gan");
String s2= new String("gan");
if(s1==s2)
System.out.println("true");
else
System.out.println("false");

Integer i1 = new Integer("1");
Integer i2 = new Integer(1);
if(i1==i2)
System.out.println("true");
else
System.out.println("false");

Integer i3 = Integer.valueOf("1");
Integer i4=Integer.valueOf("1");
System.out.println((i3==i4));

Boolean b3 = new Boolean("TRue");
Boolean b4 =new Boolean("true");
System.out.println((b3==b4));

Boolean b1 = Boolean.valueOf("true");
Boolean b2 = Boolean.valueOf("true");
System.out.println((b1==b2) );
}

}



My guess was
false
false
false
false
false
but the answer when compiled and executed was
false
false
false
false
true

Can any one explain the answers and the reason why is it so there is strange behavior in Boolean Wrapper class. Is it because it has Boolean.FALSE and Boolean.TRUE constants.Please clarify my doubt.

Thanx in advance
ganesh
Jay Pawar
Ranch Hand

Joined: Aug 27, 2004
Posts: 411

I think this code will give compilation error . Because of this line :Integer i1 = new Integer("1");


There is no compilation error. The constructor for Integer wrapper class can take primitive int or String as parameter.
[ January 10, 2005: Message edited by: Jay Pawar ]

Cheers,<br />Jay<br /> <br />(SCJP 1.4)<br />Heights of great men were not achieved in one day, they were toiling day and night while their companions slept.
Jay Pawar
Ranch Hand

Joined: Aug 27, 2004
Posts: 411
Ganesh,
To answer your question why the following code returns true.

Boolean b1 = Boolean.valueOf("true");
Boolean b2 = Boolean.valueOf("true");
System.out.println((b1==b2) );

I would suggest you to look into the implementation of valueOf() function in Boolean.java. You can find this in the directory where you have installed j2sdk. There should be a winzip file viz: src.zip. Open the zip file and look for Boolean.java file in that.
If you still do not understand why it is returning true. I will be glad to help you.

Hope this helps you...
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
If your Java purist soul prevents you from reading the source code, just scroll up to the API write-up for
public static Boolean valueOf(boolean b)
and you'll see the explanation.

This would make a great interview question for a self-proclaimed Java expert.


Mike Gershman
SCJP 1.4, SCWCD in process
Sulbha Jan
Ranch Hand

Joined: Jan 02, 2005
Posts: 37
Hello,
I still did not figure out but gave it a shot, please explain further..

I went through the Boolean.java source code for the same.
This is what I understood-
There are two Boolean objects TRUE and FALSE in the Boolean class which are defined as static and final. So every object of type Boolean will share these objects (since they are static).
Now when the static method valueOf() is invoked with "true" as the argument passed, then this method returns the Boolean object TRUE and this object is preinitialized to boolean primitive true.
b1 and b2 are two object references so what confuses me is when we say b1==b2 we are actually testing whether they refer to the same object. So does that mean b1 and b2 are referring to the same object ? Looking at the src code I am still not crystal clear??? Please dont hold the suspense any more !!!

Thanks
Sim Kim
Ranch Hand

Joined: Aug 06, 2004
Posts: 268
Mike,

Does this mean that for Integer.valueOf(String s): a new Integer is created but for Boolean.valueOf(String s) : a new Boolean is not created.
Martin Mathis
Ranch Hand

Joined: Dec 20, 2004
Posts: 45
well, if valueOf always returns Boolean.TRUE or Boolean.FALSE, and Boolean.TRUE and Boolean.FALSE are static so there is only one instance, then the two references you have will be refering to the one and only Boolean.TRUE.
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
Exactly.

From the API doc for Boolean.valueOf(boolean):

Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance.

[ January 10, 2005: Message edited by: Mike Gershman ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Does this mean that for Integer.valueOf(String s): a new Integer is created but for Boolean.valueOf(String s) : a new Boolean is not created.

Your understanding of Boolean.valueOf() is correct. For Integer.valueOf() however, we don't really know whether a new instance will be created. The API offers no specific guarantees about this. In the source for JDK 1.5.0 from Sun, it looks like it will return a new Integer for any int outside the range [-128,127], while it will reuse a permanently-cached value for any int inside that range. However this is only the way this particular JDK implementation works. Other JDKs past or future may do it differently. So it is inadvisable to rely on behavior which is not specified in the API. The best answer is: Integer.valueOf() may or may not return a new object when called. We don't really know.


"I'm not back." - Bill Harding, Twister
ganesh subbiah
Ranch Hand

Joined: Nov 18, 2004
Posts: 39
Hi All,
I posted ths question late night and went home and was really amazed to see
so many responses for my doubt Thank You all. I have responded to every one
in this long mail.Do answer my clarifications and doubts with patience.

Jay I gone through the source code of Boolean.java and found it useful.
Sorry Mike for doing so I couldn't resist my curiosity.
Mike You have referred the API documentaion for valueOf(boolean)
From the API doc for Boolean.valueOf(boolean):

quote:
--------------------------------------------------------------------------------
Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance.
--------------------------------------------------------------------------------



But i am referring to valueOf(String),for whic the API doc says:
From java API Documentaion:

public static Boolean valueOf(String s)Returns a Boolean with a value represented by the specified String. The Boolean returned represents the value true if the string argument is not null and is equal, ignoring case, to the string "true".
Example: Boolean.valueOf("True") returns true.
Example: Boolean.valueOf("yes") returns false.

Parameters:
s - a string.
Returns:
the Boolean value represented by the string.


So it will not create any instance at all , It just assigns value to a Boolean varaible. So no instances are created in both the cases(refer code)
hence its like comapring 1==1 (primitive == comparison) ,hence the result
Correct me if i am wrong.Also from the source code file for this method

public static Boolean valueOf(String s) {
return toBoolean(s) ? TRUE : FALSE;
}
private static boolean toBoolean(String name) {
return ((name != null) && name.equalsIgnoreCase("true"));
}
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}



Check what will happen if use b1= Boolean.valueOf(true)
and b2= Boolean.valueOf(true)and check for b1==b2 , i guess its false


Hi Jim,
Regarding your clarification on Integer.valueOf()method from the API documentation its given that

Returns an Integer object holding the value of the specified String. The argument is interpreted as representing a signed decimal integer, exactly as if the argument were given to the parseInt(java.lang.String) method. The result is an Integer object that represents the integer value specified by the string.

So i believe it always returns an object so i couldn't get your discrepancy
that you have expressed about this method.so please throw light on this .If in exam we get a question on Garbage Collection
what will happen to this code

public class Kirving{
public static void main(String argv[])
{
Integer i3 = Integer.valueOf("1");
Integer i4=Integer.valueOf("1");
System.out.println((i3==i4));

Boolean b3 = new Boolean("TRue");
Boolean b4 =new Boolean("true");
System.out.println((b3==b4));

Boolean b1 = Boolean.valueOf("true");
Boolean b2 = Boolean.valueOf("true");
System.out.println((b1==b2) );

i3=i4=b3=b4=b1=b2=null //line 1

}

}
How many objects are eligible for garabge collection and how many objects
were created before that???


Thanx in advance
Ganesh
Andris Jekabsons
Ranch Hand

Joined: Jan 20, 2004
Posts: 82
This code will not compile, as you are trying to assing a Boolean obj to Integer (even though they are all null). Line (1) should be changed to:
i3=i4=null; b3=b4=b1=b2=null; //line 1
But aside from that your code would create 2 Integer and 2 Boolean (b3 & b4) objects. They should be eligible for gc.
Correct me if I'm wrong.
Andris
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Ganesh]: So i believe it always returns an object so i couldn't get your discrepancy

Integer.valueOf(String) always returns an object. Nowhere is it said that it returns a new object.

My previous comments were about Integer.valueOf(int) rather than Integer.valueOf(String). For the latter, it turns out that Sun's JDK 1.5.0 does always return a new Integer object. However this is not in any way guaranteed. It may be that in JDK 5.1 or 6.0 they release an implementation which uses Integer.valueOf(int) internally, and caches Integer objects for int values in [-128,127]. Or maybe some other implementation. So, Integer.valueOf(String] may or may not return a object each time it's invoked. You have no way of knowing for sure, unless you know exactly what JDK is being used, and analyze the source code.

[Ganesh]: How many objects are eligible for garabge collection and how many objects
were created before that???


Well, if we correct for the compilation error: I'd say from 2 to 4. 4 using Sun's JDK 1.5.0. Other implementations may allow only 2 or maybe 3 objects to be garbage collected. Note that as far as I can tell, Boolean.TRUE will never be collected (unless the JVM exits, or the Boolean class itself is unloaded for some extraordinarily odd reason). If a JVM were to implement Integer.valueOf(String) using a permanent cache, then Integer.valueOf("1") would never be collected either. But we have no way of knowing that.

Note that the real exam will not depend on such unknowable trivia. (And it probably won't depend on knowable trivia such as the exact behavior of Boolean.valueOf() either - but I suppose that's less certain. There are far more useful things to learn about in Java.
[ January 11, 2005: Message edited by: Jim Yingst ]
ganesh subbiah
Ranch Hand

Joined: Nov 18, 2004
Posts: 39
Hi andris,
Thanx for pointing out the mistake.

Jim thanx for ur clarification... Though it may not be probably in the exam yet , it was a nice learning

Ganesh
 
wood burning stoves
 
subject: Explain the strange behavior of Boolean Class??
 
Similar Threads
Doubt - 'valueOf' method
Doubt in Wrapper
bitwise operator precedence
Inconsistent Wrapper Class Rule
Boolean: valueOf() and equality doubt