SF/JavaOne, Day 2, JavaGotchas

Just got out of the Java-Gotchas talk being held by Google Engineers
Josh Bloch and Neal Gafter.  It was a whole bunch of fun, and i
have to admit that even with my extensive java knowledge i was thrown
by several of the questions.  For those who don't know, this
seminary (also pionered by Eric Gunnerson) is about presenting very
simple code sample to the audience that very often do not do what you'd
expect it to do.  The audience then votes on a set of possible
answers and then the presenters reveal which is the right answer and
give a "moral" that developers can abide by to help create the clearest
code possible.

Afterwards though i ended asking myself "why did you think that the
code would behave differently than it actually would?"  And i
started thinking about how the code would behave in C# and i realized
that it would in fact be different and would end up behaving far more
intuitively than they would in java.  I ended up coding these up
to be sure, and... yup... in the end, more than half of the problems
end up behaving as one would expect in C#.

The ones that behave weirdly in both C# and Java are worth taking a
look at.  For example, this one threw me completely off:

 public class AnimalFarm
{ 
    static void main(String[] args)
    {
        final String pig = "length: 10";
        final String dog = "length: " + pig.length();

        System.out.println("Animals are equal: " + pig == dog);
    }
}

The question was: What will the above code print when run.  The possible answers were:

  1. "Animals are equal: true"
  2. "Animals are equal: false"
  3. It depends (perhaps on compiler or VM)
  4. None of the above.

So i'm sitting there, (all arrogant like), saying: "well, in C# it
would print 'Animals are equal: true' as you'd expect, and in java it will be at best '2' and at worse '3' depending on
whether or not the compiler/runtime is willing to intern values which it can statically determine with flow analysis".

What did you think the answer what?  Think about it a bit, then scroll down.

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

Think you've got it?  Well, the answer is "D: None of the
above".  Why?  Because precedence rules dictate that the
above statement will actually get parsed as:

 ("Animals are equal: " + pig) == dog

Which would then ask the question: Is "Animals are equal: length: 10" equal to "length:
10"? And no matter if it's doing reference or value equality, the
answer is always "false" and so both languages will print out "false"
to the console.

That was some egg on my face, and it got me thinking that maybe it
would be appropriate to have tools in place to help warn users about
these sorts of mistakes they might be making since it's possible it's
not what they intended. Tough to tell, but worth giving some
though to.