Я считаю, что это относится ко всем статически типизированным языкам:
String s = "some string";
Object o = s; // ok
String x = o; // gives compile-time error, o is not neccessarily a string
String x = (String)o; // ok compile-time, but might give a runtime exception if o is not infact a String
Typecast говорит: предположите, что это ссылка на класс приведения и используйте его как таковой. Теперь предположим, что o является действительно целым числом, предполагая, что это строка не имеет смысла и даст неожиданные результаты, поэтому требуется проверка во время выполнения и исключение, чтобы уведомить среду выполнения о том, что что-то не так .
При практическом использовании вы можете написать код, работающий с более общим классом, но привести его к подклассу, если вы знаете, что это за подкласс, и вам нужно обращаться с ним как таковым. Типичным примером является переопределение Object.equals (). Предположим, у нас есть класс для автомобиля:
@Override
boolean equals(Object o) {
if(!(o instanceof Car)) return false;
Car other = (Car)o;
// compare this to other and return
}