Операторы сдвига также манипулируют битами. Они могут использоваться исключительно с примитивными, целыми типами. Оператор сдвига влево (<<) производит действия над операндом, расположенным слева от оператора, сдвигая влева на число бит, указанное после оператора (вставляя нули в биты младшего порядка). Оператор сдвига вправо с учетом знака (>>) производит действия над операндом, расположенным слева от оператора, сдвигаяя вправо на число бит, указанное после оператора. Сдвиг в право с учетом знака >> использует знаковое дополнение: если значение положительное в биты старшего порядка вставляются нули; если значение отрицательное, в старшие биты вставляются единицы. Java также добавлен беззнаковый сдвиг вправо >>>, который использует дополнение нулями: независимо от знака, в старшие биты вставляются нули. Этот оператор не существует ни в C, ни в C++.
Если вы сдвигаете char, byte или short, это переводится в int перед сдвигом, а результат будет типа int. Будут использоваться только пять младших бит с правой стороны. Это предохранит вас от сдвига на болешее число бит, чем есть в int. Если вы работаете с long, в результате вы получите long. Будут использоваться только шесть младших бит с правой стороны, так что вы не сможете сдвинуть на большее число бит, чем есть в long.
Сдвиг может быть скомбинирован со знаком равенства (<<= или >>= или >>>=). lvalue заменяется на lvalue, сдвинутое на правое rvalue. Однако, есть проблема с беззнаковым правым сдвигом, скомбинированным с присваиванием. Если вы используете byte или short, вы не получаете корректный результат. Вместо этого происходит преобразование к int и правый сдвиг, но затем происходит усечение, так как результат снова присваивается к той же переменной, так что в этих случаях вы получите -1. Приведенный пример демонстрирует это:
//: c03:URShift.java
// Проверка беззнакового правого сдвига.
public class URShift { public static void main(String[] args) { int i = -1; i >>>= 10; System.out.println(i); long l = -1; l >>>= 10; System.out.println(l); short s = -1; s >>>= 10; System.out.println(s); byte b = -1; b >>>= 10; System.out.println(b); b = -1; System.out.println(b>>>10); } } ///:~