Chris said:
This code generates an "type mismatch, cannot convert from int to char"
error:
char ch = 'a';
ch = ch + 'b'; << error here
You must use a cast:
ch = (char)(ch + 'b');
On the other hand, this code does not require a cast:
char ch = 'a';
ch += 'b';
Question: is the bytecode the same for the two different ways of coding? My
gut says that it isn't, and that the cast causes extra processor cycles, but
I could be wrong.
The language spec (2nd edition -- now technically out of date with
5.0) says this:
15.26.2 Compound Assignment Operators
....
A compound assignment expression of the form E1 op= E2 is equivalent
to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1
is evaluated only once. Note that the implied cast to type T may be
either an identity conversion (§5.1.1) or a narrowing primitive
conversion (§5.1.3).
There's two things: The expression must specify an identity or
narrowing primitive conversion; and "E1 is evaluated only once".
Now I compiled your code:
public static void main(String[] args) {
char c = 'a';
c = (char) (c + 'b');
char d = 'a';
d += 'b';
}
and decompiled it with javap; and the two variations do indeed produce
exactly the same bytecode.
However, as the language spec states: with the compound operator, E1
is only evaluated once. In theory this means there may be a situation
where this leads to shorter code.
I did manage to concoct one -- that I think I may vaguely remember
from a discussion on the net in the past:
public static void main(String[] args) {
x = 0;
int[] i = new int[] { 0 };
i[x()] += x();
x = 0;
int[] j = new int[] { 0 };
j[x()] = j[x()] + x();
}
static int x() {
return x++;
}
static int x;
Here you see the first assignment succeeds as you would hope; however,
and as you probably expect, the second array access: j[x()]: raises an
ArrayIndexOutOfBoundsException.
I could have posted a better example! -- One that shows that the
compound operator saves you bytecode yet you'd have to decompile it --
or else analyse it! -- to see that -- since it has no side effects.
Change the above exmple so that x() returns a fixed value and that
exmple runs yet the second version of the assignment will execute the
method call twice; whereas the compund assignment version ... only
once! ;-)
.... I better javap that for myself just to be sure ...
Yup: what was a dup is now a load followed by an invokestatic.
Another question: why does the compiler always insist on promoting chars or
bytes to ints when doing any math? It's a real headache, because it means
that I constantly have to mask off and cast results back to the correct
type.
Pesky compiler!!!!!
PEACE!
- Steev.