В настоящее время я изучаю Java I / O учебник и не могу понять метод read () класса FileInputStream. Я знаю, что для каждого документа метод read () читает «байт» данных из потока и возвращает целое число, представляющее байт (от 0 до 256) или -1, если он достигает конца файла.
Байт в java имеет диапазон от -128 до 127, поэтому, когда я отредактирую xanadu.txt и добавлю символ ASCI "ƒ" (который имеет десятичное значение 131), java не жалуется, выдавая ошибку, что значение 131 находится вне диапазона, определенного байтом (-128 и 127)? Когда я пытаюсь проверить это с помощью литералов, я получаю два разных результата.
Следующее работает:
byte b = 120;
int c = b;
System.out.println((char)c);
Output: x
Но это НЕ работает (даже если оно работает при добавлении в xanadu.txt) :
byte b = 131;
int c = b;
System.out.println((char)c);
Output: error: incompatible types: possible lossy conversion from int to byte
byte b = 131;
Я попытался явным образом привести с использованием байта: (как это возможно?)
byte b = (byte)131;
int c = b;
System.out.println((char)c);
Output: テ
Я новичок ie, когда дело доходит до потоков ввода-вывода, кто-то пожалуйста, помогите мне понять это.
РЕДАКТИРОВАТЬ: Оказывается, мне не хватало моих знаний о понятиях приведения типов, особенно в понимании различий между «расширением» и «сужением». Ознакомление с этими понятиями помогло мне понять, почему работает явное (иначе говоря, сужение) приведение типов.
Позвольте мне объяснить: посмотрите на 3-й блок кода, где я явно преобразую литерал «131» в тип байта. Если мы хотим преобразовать литерал 131 в двоичную форму 32-разрядного целого числа со знаком 2 со знаком, мы получим 00000000 00000000 00000000 10000011, что составляет 32 бита или 4 байта. Напомним, что Java тип данных 'byte' может содержать только 8-разрядное целое число со знаком 2 со знаком, поэтому 131 находится вне диапазона, и, таким образом, мы получаем ошибку "возможное преобразование с потерями из int в байты". Но когда мы явно приводим его к байту, мы «обрезаем», или правильный термин будет «сужать» двоичное число до 8-битного целого числа. Таким образом, когда мы делаем это, то получаемый двоичный файл равен 10000011, который равен -125 в десятичном значении. Поскольку -125 находится в диапазоне от -128 до 127, у байта нет проблем с его принятием и хранением. Теперь, когда я пытаюсь представить значение байта в int c, происходит неявное или «расширяющее» приведение, где -125 в двоичной форме 8-битного 10000011 преобразуется в эквивалентный -125 в двоичной форме 32-битного 11111111 11111111 11111111 10000011. Наконец, system.out пытается вывести значение (char) c, которое является другим явным или «сужающимся» приведением, когда оно пытается сжаться с 32-разрядной подписи до 16-разрядной подписи без знака. Когда приведение завершено, мы получаем 11111111 10000011 в двоичном виде. Теперь, когда этот двоичный файл преобразован в символьную форму с помощью java, он возвращает テ.
В заключение я могу сказать, что это помогает преобразовать все в двоичную форму и go оттуда. Но убедитесь, что вы понимаете кодировку и дополнение 2