Java char для байтового каста

Я тестировал кастинг char, и я прошел через это:

public class Test {
    public static void main(String a[]) {
        final byte b1 = 1;
        byte b2 = 1;
        char c = 2;

        c = b1; // 1- Working fine
        c = b2; // 2 -Compilation error
    }
}

Может ли кто-нибудь объяснить, почему он работает нормально в 1, когда я добавил финал в байт?

Ответ 1

Когда переменная final, компилятор автоматически устанавливает значение, равное 1. Это значение представляется как char, i.e.:

c = b1;

эквивалентно

c = 1;

Фактически, в соответствии с в этом разделе переменных final b1 рассматривается как константа:

Переменная примитивного типа или типа String, то есть final и инициализированная выражением константы времени компиляции (§15.28), называется постоянной переменной.

Ответ 2

Преобразование из byte в char является расширением и сужением примитивного преобразования, как описано в параграфе 5.1.4 спецификации языка Java.

Как описывает JLS, это делается через промежуточный этап; byte преобразуется в int посредством расширения примитивного преобразования, а затем int преобразуется в char через сужение примитивного преобразования (см. 5.1.3).

Параграф 5.2 объясняет, когда при выполнении задания требуется бросок:

... если выражение является выражением константа (§15.28) типа byte, short, char, или int:

  • Сужение примитивного преобразования может быть использовано, если тип переменной byte, short или char, а значение константного выражения представлено в типе переменной.

Ваша переменная b1 действительно является константой, но ваша переменная b2 не является, поэтому это правило применяется для b1, но не для b2.

Итак: вы можете назначить b1 на c, потому что b1 является константой, а значение константы 1 соответствует char, но вы не можете назначить b2 c без трансляции, потому что b2 не является константой.

Ответ 3

Ну, потому что байт является подписанным типом, а char - нет, поэтому вам нужно применить явное преобразование типа для (2)

c = (char)b2;

также окончательный оператор работал на 1, поскольку до компиляции компилятор может подтвердить отсутствие потерь из-за преобразования, так как "1" находится в диапазоне char, попробуйте поставить "-1" с помощью то же окончательное утверждение в (1) вы снова получите ошибку компиляции.

Все это сводится к совместимости типов между подписанными и неподписанными типами. Это должно быть сделано явно в java.