Actually, it's worse than that.
In both Java and C/C++, doing this kind of thing actually makes code slower. It only makes sense in assembler.
When the compiler can deduce that two variables already in registers have swapped value, it simply relabels the registers, making swap a 0-cost operation. Obviously if are swapping two memory locations, you have to read, but a temporary optimises to:
mem1 -> reg1
mem2 -> reg2
reg1 -> mem2
reg2 -> mem1
While a swap trick, if the compiler can't backward-enginner it out has to add a bit of xoring (or adding).
gcc actually has an optimisation pass with the specific job of trying to take out this trick. Unfortunately, it can't always work because if you try using these tricks on two pointers to the same memory location, you end up zeroing out the value rather than doing nothing (which a proper temporary would).