[quote]You have to bracket the x+y, to make the compiler interpret that plus as an integer plus, rather than a String concatenate. Minor irritant.
[/quote]
Well, that’s just because the expression is evaluated in left-right order. The String’s + operator has the same precedence as the int’s + operator, so you need to explicitly bracket things.
[quote]What really really irritates me about this example is that javac will refuse to compile (which is a whole separate stupidity: compiler warning? yes please … refuse to compile? Please, NO!) if it thinks I didn’t actually want an automatic cast for this:
float f = f * Math.sqrt( f );
when I often do want the cast, but WILL NOT do the same behaviour for the painfully common accident I highlighted above.
[/quote]
Well, it’s all logical I’m afraid!
In the sqrt expression, (float * double) is promoted to (double * double), which is evaluated. It then tries (float = double), which fails to compile as it’s a narrowing conversion.
In the integer divide expression, (int / int) is evaluated first (as an integer divide, as both operands are integers), then it attempts (double = int), promotes it to (double = double) via a widening conversion, which then works fine. ;D
N.B. Some languages get around this kind of problem by having a different operator for integer divides.
[quote]Ditto the stupid stupid stupid bug whereby:
Object i = null; // you HAVE to explicitly reference null, or it won't compile
// do something with i
is forced upon you by the compiler because otherwise it refuses to compile because “i may not have been assigned to”. What do I gain? If I try using it without assignment, I’m STILL going to get a NullPointerException; the only difference is that now I’ve had to write extra code…Sigh.
[/quote]
Nope, not a bug - there’s a big difference there.
Local variables are NOT implicitly initialised - you have to do it yourself. (Member variables are automatically initialised at object creation.) If you didn’t explicitly assign a value to a local variable, you wouldn’t get a NullPointerException, you’d get garbage - a reference pointing to some random bit of memory somewhere. The Java compiler refuses to allow this to happen, so you have to initialise it.
And why doesn’t Java implicitely initialise local variables? It’s to allow you to perform late-initialization of local final variables! 