Максим Федоров, я думал (может ошибка моя) что тип объекта становится известен системе при выполнении. А если он до выполнения не известен – как ещё при компиляции определяется ошибка, говорящая что типы не подходят.
Нет, в джаве статическая типизация. Типы известны во время компиляции. В твоём примере типы объекта и переменной известны и не совпадают(и тип объекта не может быть приведён к типу переменной).
Почему того компилятору до выполнения не известно, к какой именно версии переопределённого метода произойдёт обращение? (Доказательство ниже).
Если тип объект уже известен при компиляции – понятно же что к версии этого типа.
class Solution0 {
void test() throws Exception {
throw new Exception();
}
}
class Solution extends Solution0 {
void test() {
}
public static void main(String[] args) {
Solution0 object = new Solution();
object.test(); // ошибка компиляции (заставляет обработать исключение) – хотя в методе, который был бы вызван вообще нет исключений.
Solution object2 = (Solution) object;
object2.test(); //а здесь уже нет ошибки компиляции (хотя тот же самый метод будет вызван)
}
}
Сергей, вообще то один и тот же метод – вызывается всегда самый актуальный в объекте, возьми и выполни. А то что типы разные – какая разница, если компилятор не знает к какому обратится, как я и написал, – суть не меняется.
go2goj, потому что статическая типизация. И динамический полиморфизм. Ты сам сказал компилятору, какого типа будет переменная, и он тебе верит. Ты в эту переменную присвоил потомка - происходит автоматическое приведение типа потомок -> предок, всё ок. Ты вызываешь метод у предка - компилятор видит, что этот метод может бросать исключение, и заставляет тебя проверить.
Дальше ты руками хардкастишь предка к потомку(а попробуй убрать каст) и вызываешь метод потомка, который не бросает исключения. Поэтому проверка не нужна.
В момент каста может случиться ClassCastException, если в переменной типа предка лежит не потомок, кастом ты об этом просишь. Поэтому в переменную типа потомок может попасть только потомок или его потомки.
1. Да, тип объектов –во-время выполнения.
2. Нельзя скомпилировать, потому что по классу уже определён тип ссылки (как литерала) – и он не подходит.
Тип ссылки и объекта – разные вещи.