Tyler has posted 1 posts at DZone. View Full User Profile

Interesting Java Language Puzzle

08.27.2010
| 6267 views |
  • submit to reddit
We ran into an unexpected result as part of Java's auto boxing feature. At least I think it is related to auto boxing. See the following code snippet
package com.foo;

public class AutoBoxTest {

	public static void main(String[] args) {
		Boolean abc = new Boolean(false);
		setMe(getThisValue() || abc == null? false: abc); 
	}
	
	static public Boolean getThisValue() {
		return new Boolean(true);
	}
	static public void setMe(Boolean pValue) {
		System.out.println("Value is : " + pValue);
	}
}

The result? Value is : false

Huh? It turns out changing the call to setMe() as follows "fixes" the issue, I'd just like to know if anyone can explain why?

   Boolean abc = new Boolean(false);
   setMe(getThisValue() || (abc == null? false: abc)); 

The result is: Value is : true Strange.

2.333335
Your rating: None Average: 2.3 (3 votes)
Published at DZone with permission of its author, Tyler Van Gorder.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Mirosław Pluta replied on Fri, 2010/08/27 - 5:16am

Well, it's quite obvious. It's about operators precedence: http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html   || binds stronger than the ternary operator, so what you're executing is :

(getThisValues() || abc == null ) ? false : abc

Philipp Neumann replied on Fri, 2010/08/27 - 5:16am

Look up operator precedence:

setMe(getThisValue() || abc == null? false: abc);   

is similar to

setMe((getThisValue() || abc == null) ? false: abc); 

and is always false.

Mustafa Dasgin replied on Fri, 2010/08/27 - 5:25am

It is about operator precedence. Try this: public class NormalTest { public static void main(String[] args) { boolean abc = false; setMe(getThisValue() || abc != false? false: abc); } static public boolean getThisValue() { return true; } static public void setMe(boolean pValue) { System.out.println("Value is : " + pValue); } } Again false..

Jim Frohnhofer replied on Fri, 2010/08/27 - 8:13am

While you're at it, check the Javadocs on Boolean:

 

Note: It is rarely appropriate to use this constructor. Unless a new instance is required, the static factory valueOf(boolean) is generally a better choice. It is likely to yield significantly better space and time performance.

 

Tyler Van Gorder replied on Fri, 2010/08/27 - 10:58am

Thanks, makes total sense.

Vassil Stoyanov replied on Fri, 2010/08/27 - 11:38am

Operator priority ??

Claude Lalyre replied on Fri, 2010/08/27 - 7:13pm

1) First case, we have
(getThisValue() || abc == null? false: abc);
i.e  (getThisValue() || abc == null) ? false: abc;
i.e (True || abc == null) ? false : abc
i.e True ? false : abc
i.e false


2) Second case, we have
getThisValue() || (abc == null? false: abc)
i.e True || (abc == null ? false : abc)
i.e True || (whatever)
i.e True

 

 

Peter Karussell replied on Mon, 2010/08/30 - 2:36am

Hey folks ... why voting his post (so much) down?? Because he is courageous and posted his nescience?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.