Ответ
Приведение объекта к его фактическому типу (downcasting) происходит во время выполнения (runtime).
Почему так:
- Компилятор проверяет только возможность приведения на основе объявленных типов в соответствии с иерархией наследования. Он не знает реальный тип объекта в памяти во время компиляции.
- JVM (Java Virtual Machine) во время выполнения проверяет реальный тип объекта и выполняет само приведение. Если реальный тип не совместим с целевым, генерируется исключение
ClassCastException.
Пример безопасного downcasting с проверкой во время выполнения:
Object obj = "Это строка"; // Объявленный тип Object, фактический тип String
// 1. Проверка типа во время выполнения (обязательна для безопасности)
if (obj instanceof String) {
// 2. Приведение во время выполнения
String str = (String) obj; // Downcasting от Object к String
System.out.println(str.toUpperCase()); // Работает
}
// Опасное приведение без проверки вызовет ClassCastException во время выполнения:
// Integer num = (Integer) obj; // ClassCastException: String cannot be cast to Integer
Важное исключение: Приведение примитивных типов (например, int к long) происходит во время компиляции, так как их типы и преобразования строго определены.
Итог: Для ссылочных типов компилятор лишь «разрешает» потенциально возможное приведение, а окончательная проверка и само преобразование выполняются JVM в момент работы программы.