TITLE: Java Trivia: Unary Operators in String Concatenation AUTHOR: Eugene Wallingford DATE: February 02, 2006 3:47 PM DESC: ----- BODY: Via another episode of College Kids Say the Darnedest Things, here is a fun little Java puzzler, suitable for your compiler students or, if you're brave, even for your CS1 students. What is the output of this snippet of code?
        int price = 75;
        int discount = -25;
        System.out.println( "Price is " + price + discount + " dollars" );
        System.out.println( "Price is " + price - discount + " dollars" );
        System.out.println( "Price is " + price + - + discount + " dollars" );
        System.out.println( "Price is " + price + - - discount + " dollars" );
        System.out.println( "Price is " + price+-+discount + " dollars" );
        System.out.println( "Price is " + price+--discount + " dollars" );
Okay, we all that the second println causes a compile-time error, so comment that line out before going on. After you've made your guesses, check out the answers. Many students, even upper-division ones, are sometimes surprised that all of the rest are legal Java. The unary operators + and - are applied to the value of discount before it is appended to the string. Even some who knew that the code would compile got caught by the fact that the output of the last two printlns is not identical to the output of the middle two. These operators are self-delimiting, so the scanner does not require that they be surrounded by white space. But in the last line, the scanner is able to match a single token in -- (the unary operator for pre-decrement) rather than two unary - operators, and so it does. This is an example of how most compilers match the longest possible token whenever they have the choice. So whitespace does matter -- sometimes! This turned into a good exercise for my compiler students today, as we just last time finished talking about lexical analysis and were set to talk about syntax analysis today. Coupled with the fact that they are in the midst of writing a scanner for their compiler, we were able to discuss some issues they need to keep in mind. For me, this wasn't another example of Why Didn't I Know This Already?, but in the process of looking up "official" answers about Java I did learn something new -- and, like that lesson, it involved implicit type conversions of integral types. On Page 27, the Java Language Reference, says:
The unary plus operator (+) ... does no explicit computation .... However, the unary + operator may perform a type conversion on its operand. ... If the type of the operand is byte, short, or char, the unary + operator produces an int value; otherwise the operator produces a value of the same type as its operand.
The unary - operator works similarly, with the type conversion made before the value is negated. So, again, an operation promotes to int in order to do arithmetic. I assume that this done for the same reason that the binary operators promote bytes, shorts, and chars. Like many CS professors and students, I enjoy this sort of language trivia. I don't imagine that all our students do. If you'd like to see more Java trivia, check out Random Java Trivia at the Fishbowl. (You gotta love the fact that you can change the value of a string constant!) I've also enjoyed thumbing through Joshua Bloch's and Neal Grafter's Java Puzzlers. I am glad that someone knows all these details, but I'm also glad not to have encountered most of them in my own programming experience. -----