Yes, this is weird indeed. I had some unexpected behavior from the previous IDE I used (JDeveloper). It was too tolerant but WebSphere works a lot better. For the code posted I do get the compile errors. Therefore one piece of advice, don't trust your IDE 100%.
However when I try compiling with the command line compiler (1.4.1_01) it works just fine.
From my observation, I've seen that System.out.println() works in the following way : 1. If a String comes first, a string concat happens. System.out.println ("str"+1+2) => str12 2. If some other data types come first, it tries to determine the output of that and then do the string concat. System.out.println (1+2+"str"); => 3str If it fails to determine the output of the arguments appearing before the String type, it will not compile. Example, System.out.println (1+true+"str") and System.out.println(1+true) 3. System.out.println (null) will give a compile error "ambiguous reference", because null can be treated as char or String or something else maybe. 4. However, if null is APPENDED with any other data type, it is treated as a String. System.out.println(null + true); //1 System.out.println(true + null); //2 System.out.println(null + null); //3 So in the first case, it is a String + boolean In the 2nd case, it is boolean + String In the 3rd case, it is String + String Now consider System.out.println (true+true+null); This will not compile because operator + can't be applied to boolean. Here it first tries to find the outcome of the first two arguments. (see point 2) Also it is interesting to note the following: String as1 = new String (null) gives the compile error "reference to String is ambiguous because null can be treated as both String and StringBuffer". However, StringBuffer as2 = new StringBuffer(null) compiles fine, implying that null is treated as a String. Thanks, Sudd
If only one operand expression is of type String, then string conversion is performed on the other operand to produce a string at run time.
And then in 22.214.171.124, it explains how the coversion happens. In the given question, none of the operands of + are of type String, so String conversion should not happen. In the old versions of the JDK 1.2.2 (if I remember correctly), this code does not compile and rightly so. In compilers that stick to the JSL more strictly such as IBM's, this code does not compile either. In any case, this question is not very useful for the exam and has been removed. HTH, Paul.
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#40220 "... If only one operand expression is of type String, then string conversion is performed on the other operand to produce a string at run time. The result is a reference to a newly created String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string. . . .
"The + operator is syntactically left-associative, no matter whether it is later determined by type analysis to represent string concatenation or addition. In some cases care is required to get the desired result. For example, the expression: a + b + c is always regarded as meaning: (a + b) + c Therefore the result of the expression: 1 + 2 + " fiddlers" is: "3 fiddlers" ..."
So that explains what happens. true + null and null + true are both Strings. null is converted from it's reference type, the null type, represented by the literal null(§3.10.7), to a String. But true + true + null will be evaluated as (true + true) + null, which causes a compiler error. According to §5.1.6,
There is a string conversion to type String from every other type, including the null type.
The original code compiles and runs. If the test says that "none of the 3 will compile," then the test may be wrong. Should null be promoted to a String? It is the only type to do so. In the code example above, null is the only type that is promoted to a String itsself. null + new Integer(1) first interprets null as a String by itsself and then converts the Integer to a String. This is what happens, but is this correct?
Not useful? It made me think about the + operator for strings more. I actually thought that null should be converted into a string, even though null is a literal pointer to the null reference type. I guess I tend to side w/my compiler. I probably should trust it less.
For compilers that actually compile this, the compiler is interpreting null as a null String object. That is the only possible explanation (or is it?) It is clear now that null should not be promoted to a String object, but instead to the null reference type.