Итак, я пришел к странному поведению относительно побитовых операторов и смещению бит. Я пытался сделать небольшой чек быстрее, используя бит-маски, и я пришел к этому:
public class Weirdness {
private final static int constant = 3;
private static int notConstant = 3;
public void stuff() {
byte a = 0b1 << 3;
byte b = 0b1 << (int) 3;
byte c = 0b1 << constant;
byte d = 0b1 << notConstant; //error
byte e = 0b1 << getAnInt(); //error
byte f = 0b1 << getAFinalInt(); //error
int i = 3;
byte g = 0b1 << i; //error
final int j = 3;
byte h = 0b1 << j;
}
public static int getAnInt() {
return 3;
}
public static final int getAFinalInt() {
return 3;
}
}
a
, b
, c
и h
не дают ошибок компиляции; Но d
, e
, f
и g
do. Компилятор просит явно указать byte
или объявить последние переменные как int
. Я заметил аналогичное поведение с bitwize &
и |
тоже.
Может кто-нибудь объяснить, что здесь происходит?
Какая магия для компилятора работает для a
, b
, c
и h
для работы?
РЕДАКТИРОВАТЬ: Или как это не совсем дубликат
Я считаю, что этот вопрос отличается от того, что из Почему я не могу добавить два байта и получить int, и я могу добавить два последних байта, чтобы получить байт?, потому что что вызывает интересное поведение, так это то, как компилятор оптимизирует операции сдвига битвита.
И так как я ищу теоретический ответ (потому что я уже понимаю, что могу сделать свой код скомпилированным путем кастинга), как сдвиг и другие операции битвизации определяют их возвращаемое значение, я считаю, что этот вопрос может дополнять смещение Java-битов с целыми числами и байтами и добавление более интересной информации в StackOverflow.