Java - char, int преобразования
В Java допускается следующее:
char c = 'A' + 1;
Здесь c будет содержать значение "B". Выше сначала оценивается выражение. Таким образом, "A" преобразуется в 65, все выражение оценивается до 66, а затем 66 преобразуется в "B", так как мы сохраняем значение в char.
Ниже приведена ошибка времени компиляции:
char c = 'A';
c = c + 1;
Каково объяснение того, как Java рассматривает выражения по-разному? Кстати, следующее прекрасно работает:
char c = 'A';
c++;
Ответы
Ответ 1
Это просто спецификация. Преобразование int в char является сужающим преобразованием, а 'A' + 1
является выражением константа. Постоянным выражением является (в основном) выражение, результат которого всегда один и может быть определен компилятором. Сужение конверсий разрешено для присвоений байтов, коротких и char, когда оно является постоянным выражением.
Вот что JLS для преобразования присваивания говорит:
Сужение примитивного преобразования может быть использовано, если тип переменной является байтом, коротким или char, а значение константного выражения представляется в типе переменной.
c + 1
не является постоянным выражением, поэтому для присваивания возникает ошибка времени компиляции. Просмотрев код, мы можем определить, что результат всегда должен быть одним и тем же, но компилятор не может его определить.
Интересно, что мы можем сделать следующее:
final char a = 'a';
char b = a + 1;
В этом случае a + 1
является константным выражением, поскольку a
является окончательным.
Предостережение к константному выражению состоит в том, что следующее также не компилируется:
char c = 'A' + 99999;
Поскольку значение 'A' + 99999
не представляется в типе char.
Как и для других операторов, например ++
, которые вы упомянули, у них есть свои собственные спецификации. соответствующий бит для ++
(и аналогичным образом все приращения и декременты):
Тип выражения postfix increment - это тип переменной.
...
Перед добавлением бинарное числовое продвижение (§5.6.2) выполняется по значению 1 и значению переменной. При необходимости сумма сужается сужением примитивного преобразования (п. 5.1.3)... до типа переменной до ее сохранения.
(Предположительно, преобразование выполняется для char.) Также стоит отметить, что +=
автоматически выполняет сужение преобразования. Таким образом, c += 1;
также скомпилируется.
Ответ 2
char to int conversion называется расширением конверсий. При расширении конверсий значения не теряют информацию об общей величине числового значения, где преобразование int в char называется сужением конверсий. При сужении конверсии вы можете потерять информацию об общей величине числового значения и также потерять точность.
Для получения дополнительной информации о примитивных преобразованиях обратитесь этот документ.
Ответ 3
Это потому, что компилятор может проверить, что он ('A' + 1)
находится в пределах char, тогда как он не может (в общем) проверить, что c + <an integer>
находится в пределах.
Ответ 4
Это потому, что литералы для целых чисел или меньше, чем int в качестве байта, short и char являются int. Таким образом понимайте следующее.
код:
byte a = 10;//compile fine
byte b= 11;//compile fine
byte c = a+b;//compiler error[says that result of **a+b** is **int**]
то же самое происходит для любых математических операций, таких как "Разделить", "умножить" и другую арифметическую операцию. поэтому приведите результат, чтобы получить литерал в желаемом типе данных
byte c = (byte)(a+b);
поэтому, когда вы выполняете
c= c+1;//compiler error
Его результат c + 1 является int не a char. поэтому компилятор дает ошибку времени компиляции для того же самого.
поэтому вам нужно предоставить примитивный эффект, чтобы изменить литерал на тип данных char.
Надеюсь, что этот пример дает некоторое понимание.