Расширяющие и сужающие преобразования
Изучите автоматические расширяющие преобразования и безопасное выполнение явных сужающих приведений.
«Расширяющие и сужающие преобразования» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Преобразование типов в Java
Java позволяет преобразовывать значения между совместимыми типами. Существует два направления:
- Расширяющее преобразование — преобразование в тип большего размера (безопасное, выполняется автоматически)
- Сужающее преобразование — преобразование в тип меньшего размера (рискованное, требует явного приведения)
Расширяющее преобразование
Расширяющее преобразование выполняется автоматически, когда значение присваивается совместимому типу большего размера. Данные не теряются, поскольку целевой тип может представить все значения исходного.
Порядок расширения: byte → short → int → long → float → double
byte b = 42;
short s = b; // byte → short (widening)
int i = s; // short → int (widening)
long l = i; // int → long (widening)
float f = l; // long → float (widening)
double d = f; // float → double (widening)
System.out.println(d); // 42.0Сужающее преобразование
Сужающее преобразование необходимо выполнять явно с помощью оператора приведения (type). Значение может быть усечено или искажено, если оно не помещается в целевой тип.
double price = 99.99;
int wholePart = (int) price; // narrows — decimal truncated
System.out.println(wholePart); // 99 (not rounded!)
long bigNum = 130L;
byte small = (byte) bigNum; // 130 overflows byte (max 127)
System.out.println(small); // -126 (unexpected!)Переполнение при сужающем преобразовании
При переполнении во время сужающего преобразования Java зацикливает значение с использованием модульной арифметики — исключение не выбрасывается. Защититься от этого необходимо самостоятельно.
int million = 1_000_000;
byte narrowed = (byte) million;
System.out.println(narrowed); // 64 (wraps around)
// Safe narrowing: check bounds first
if (million >= Byte.MIN_VALUE && million <= Byte.MAX_VALUE) {
byte safe = (byte) million;
} else {
System.out.println("Value doesn't fit in byte!");
}Преобразование char и int
char — это 16-битное беззнаковое целое число, представляющее кодовую точку Юникода. Оно автоматически расширяется до int, но обратное преобразование из int в char требует явного приведения.
char letter = 'A';
int code = letter; // widening: char → int
System.out.println(code); // 65
int nextCode = code + 1;
char nextLetter = (char) nextCode; // narrowing: int → char
System.out.println(nextLetter); // B
// Useful for Caesar cipher shifts
char shifted = (char) ('a' + 3);
System.out.println(shifted); // dУсечение числа с плавающей точкой до целого
Приведение числа с плавающей точкой к целому усекает его в сторону нуля — округления не происходит. Если необходимо округление, используйте Math.round().
double pos = 3.9;
double neg = -3.9;
System.out.println((int) pos); // 3 (not 4)
System.out.println((int) neg); // -3 (not -4)
System.out.println(Math.round(pos)); // 4
System.out.println(Math.round(neg)); // -4Преобразование String в число
Разбор значения String в число выполняется с помощью методов классов-обёрток, а не приведением типов. Передача строки, не являющейся числом, вызывает NumberFormatException.
String input = "42";
int parsed = Integer.parseInt(input);
double parsedD = Double.parseDouble("3.14");
System.out.println(parsed + 1); // 43
System.out.println(parsedD); // 3.14
try {
int bad = Integer.parseInt("abc");
} catch (NumberFormatException e) {
System.out.println("Not a valid number!");
}Преобразование числа в String
Преобразовать число в String можно с помощью String.valueOf(), Integer.toString() или конкатенации со строкой "".
int score = 95;
String s1 = String.valueOf(score); // "95"
String s2 = Integer.toString(score); // "95"
String s3 = score + ""; // "95" (concat trick)
System.out.println(s1.getClass().getSimpleName()); // String
// Converting to different bases
System.out.println(Integer.toBinaryString(42)); // 101010
System.out.println(Integer.toHexString(255)); // ffПовышение типов в выражениях
В арифметических выражениях Java автоматически повышает тип операндов:
byte,short,char→ перед выполнением операции приводятся кint- Если один из операндов имеет тип
long, результат будет иметь типlong - Если один из операндов имеет тип
floatилиdouble, результат будет иметь более широкий из этих типов
byte x = 10;
byte y = 20;
// byte z = x + y; // compile error! sum is promoted to int
int z = x + y; // correct
long a = 100L;
float b = 2.5f;
double result = a * b; // long * float → double
System.out.println(result); // 250.0Составные операторы присваивания
Составные операторы, такие как +=, -=, *=, включают неявное сужающее приведение. Благодаря этому можно писать более компактный код с переменными типа byte и short.
byte count = 100;
// count = count + 1; // compile error — int result needs cast
count += 1; // OK — compound op casts automatically
System.out.println(count); // 101
short total = 1000;
total *= 2; // implicit narrow cast included
System.out.println(total); // 2000Практика: безопасный разбор целых чисел
Практический шаблон: безопасно разобрать пользовательский ввод, проверить диапазон и привести значение к нужному точному типу.
public static byte parseAsByte(String input) {
int value = Integer.parseInt(input); // can throw NumberFormatException
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
throw new IllegalArgumentException(
"Value " + value + " out of byte range");
}
return (byte) value;
}
// Usage
System.out.println(parseAsByte("100")); // 100
System.out.println(parseAsByte("200")); // IllegalArgumentExceptionБыстрая проверка
Каков результат выполнения следующего кода?
double d = -7.8; int i = (int) d; System.out.println(i);
Итоги: расширение и сужение типов
Основные выводы:
- Расширяющее преобразование выполняется автоматически и безопасно: byte→short→int→long→float→double
- Для сужающего преобразования нужно явное приведение, при этом возможна потеря данных или переполнение
charрасширяется доint;intможно сузить обратно доcharс помощью приведения- Преобразование числа с плавающей точкой в
intотбрасывает дробную часть к нулю, а не округляет число - Используйте Integer.parseInt/Double.parseDouble для преобразования String в числа
- Составные операторы (+=, *=) включают неявное сужающее приведение
Часто задаваемые вопросы
Урок «Расширяющие и сужающие преобразования» бесплатный?
Да — полный текст урока «Расширяющие и сужающие преобразования» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Расширяющие и сужающие преобразования»?
Изучите автоматические расширяющие преобразования и безопасное выполнение явных сужающих приведений. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Расширяющие и сужающие преобразования»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Примитивные и ссылочные типы
- Расширяющие и сужающие преобразования
- Оператор instanceof
- Приведение типов на практике