Кастинг типов
Кастинг — это преобразование значения из одного типа в другой. Бывает двух видов, и Java относится к ним по-разному.
Неявное (widening) — Java делает сама. Когда «меньший» тип точно влезает в «больший» без потерь:
int x = 10;
double y = x; // int → double, безопасно, само превратилось
Явное (narrowing) — нужно указать тип в скобках. Когда есть риск потерять данные, компилятор требует подтверждения:
double price = 9.99;
int whole = (int) price; // явно говоришь: "да, хочу обрезать"
// whole == 9 — дробная часть просто отброшена
(int) перед значением — это и есть кастинг: «преврати в int, мне нужно именно так».
Копнуть глубже
Потеря точности при сужении — не ошибка, а тихая обрезка:
int big = 130;
byte b = (byte) big; // byte вмещает только -128..127
// b == -126, число "переполнилось" и пошло по кругу
Компилятор не предупредит во время выполнения — просто получишь неожиданное число. Поэтому сужающий кастинг — это всегда явное «я понимаю, что делаю».
Кастинг объектов — другая история. Это не превращение типа, а проверка: «а можно ли смотреть на этот объект как на другой тип»:
Object obj = "текст";
String s = (String) obj; // ок, там реально String
Object n = 5;
String bad = (String) n; // ClassCastException — там Integer, не String
Если внутри объект не того типа — программа упадёт с ClassCastException в рантайме, а не на этапе компиляции.
Под капотом
Для примитивов кастинг — это не «просто слово», а отдельная инструкция байт-кода: i2d (int → double), d2i (double → int) и так далее под каждую пару типов. JVM реально выполняет преобразование на уровне процессора, а не просто переинтерпретирует биты.
Для объектов кастинг ничего не меняет в памяти — объект как лежал, так и лежит. Кастинг лишь говорит компилятору «доверяй мне, расценивай эту ссылку как тип X», а JVM в рантайме проверяет, что это действительно так (отсюда и ClassCastException, если соврал).
• что значит потеря точности при сужении и что такое `ClassCastException` (если дошёл до 2-го слоя).