Ваше утверждение примерно эквивалентно этой расширенной форме:
x = x ^ (y = y ^ (x = x ^ y));
В отличие от C, в Java левый операнд двоичного оператора гарантированно вычисляется перед правым операндом.Оценка происходит следующим образом:
x = x ^ (y = y ^ (x = x ^ y))
x = 1 ^ (y = 2 ^ (x = 1 ^ 2))
x = 1 ^ (y = 2 ^ (x = 3))
x = 1 ^ (y = 2 ^ 3) // x is set to 3
x = 1 ^ (y = 1)
x = 1 ^ 1 // y is set to 1
x = 0 // x is set to 0
Вы можете изменить порядок аргументов для каждого выражения xor, чтобы присвоение выполнялось до повторной оценки переменной:
x = (y = (x = x ^ y) ^ y) ^ x
x = (y = (x = 1 ^ 2) ^ y) ^ x
x = (y = (x = 3) ^ y) ^ x
x = (y = 3 ^ y) ^ x // x is set to 3
x = (y = 3 ^ 2) ^ x
x = (y = 1) ^ x
x = 1 ^ x // y is set to 1
x = 1 ^ 3
x = 2 // x is set to 2
Этоболее компактная версия, которая также работает:
x = (y ^= x ^= y) ^ x;
Но это действительно ужасный способ поменять две переменные.Намного лучше использовать временную переменную.