|
|
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Дано: класс-родитель и класс-наследник. В методе класса-наследника идёт "очевидно-неправильная" попытка приведения типа (downcasting): Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Этот код, однако, компилится без проблем. Ошибка возникает только в рантайме: Код: plaintext 1. 2. 3. 4. 5. Так вот, вопросик у мну такой: компилятор разве не может засечь эту неверную попытку приведения типов ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2013, 20:56:56 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
Нет, такое приведение он отследить не может. Ведь Derv это наследник Base. Поэтому переменная b может ссылаться как на экземпляр Base так и на Derv. Сканирование всех возможных маршрутов рантайма для вычисления возможного значения какой-то переменной, это как-то уж слишком. Компилятор умеет обнаруживаь ситуации, когда переменная и класс кастинга из совсем разных иерархий. А так как множественного наследования классов нет, то переменная не может содержать в себе экземпляр из другой иерархии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2013, 21:04:05 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
хм... досадно, конечно :( с формальным параметром метода - ладно, всё ясно. Но он не "видит" бредятину еще и вот тут: Код: java 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2013, 21:12:10 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisНо он не "видит" бредятину еще и вот тут: Компилятор вычисляет только примитивы и строки. Base.<init> это, грубо говоря, метод возращающий тип Base, который может ссылаться и на Derv. Для выявления подобных проблем есть масса анализаторов кода. FindBugs, Sonar и пр. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2013, 21:23:02 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
BlazkowiczКомпилятор умеет обнаруживаь ситуации, когда переменная и класс кастинга из совсем разных иерархий .Всё-таки подниму тему. Ибо логику компилятора осилить не в состоянии до сих пор . Вот этот пример: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. - компилируется ОК, но вываливает в рантайме CCE. Что мешает компилятору послать нахрен этот код ? Здесь в наглую делается downcast к интерфейсу, который НЕ реализован классом Bird! Спотыкаюсь на этой фишке уже надцатый раз, блин... :-/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 22:36:34 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosis, вопрос интересный и провокационный. Наверное ответ лежит в том что компиллятор на какой-то фазе (opcodes) сознательно не делает проверки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 22:42:56 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
maytonozzmosis, вопрос интересный и провокационный . Наверное ответ лежит в том что компиллятор на какой-то фазе (opcodes) сознательно не делает проверки.Нет, я далёк мыслей на тему "трололо" :) Я не могу понять логику его работы вот именно в этом вопросе. Почему он не отсекает практически очевидные ляпы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 22:48:27 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
PS. Если с помощью междуморда можно скомпилировать кастинг совсем несвязанных классов, то через общий класс-предок можно сделать почти то же самое: прикастовать др. к др. классы, являющиеся собратьями (siblings) в иерархии, но также не связанные друг с другом. См. Рыбу и Птицу ниже: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. В общем, весело. Запоминать эту особенность - в лом, да и бестолку. Ибо понимания нет, почему так происходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 23:24:33 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
Я переписал исходник немножко по другому правда пришлось добавить пометку что main отбрасывает classCastException. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. И мне кажется что мой пример более общо отображает смысл создания объекта на стеке с операцией последующего кастинга. Честно я согласен с ТС что можно ужесточить проверки на этапе компилляции но javac почему-то более либерален и позволяет шире трактовать то что возвращает оператор new. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 23:40:50 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
Да, смысл еще понятнее если Class.forName("Bird").newInstance() заменить на Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.10.2013, 23:42:28 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
А в тривиальном случае (без кастинга) компиллятор сразу ругается. Код: java 1. 2. 3. 4. 5. 6. Ваш случай - одноразовый. Баг находится на первом же coverage test. Мой случай с параметризированным кастингом на неизвестный класс - понятное дело не может проверяться компиллятором. Здесь просто не напасёшся правил и "защит от дурака". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 00:21:15 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisЧто мешает компилятору послать нахрен этот код ? Здесь в наглую делается downcast к интерфейсу, который НЕ реализован классом Bird! Спотыкаюсь на этой фишке уже надцатый раз, блин... :-/ Вопрос, конечно, интересный... Я думаю, что приведения рассматриваются компилятором как переход на ручное управление, типа программист сам берет на себя ответственность за последствия. Ну берет так берет. Может, он именно что хочет чтобы здесь всегда выбрасывалось исключение. А насчет "надцатый" раз, то подозреваю, у вас плохо спроектирована система типов. Попробуйте использовать дженерики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 07:14:58 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisЯ не могу понять логику его работы вот именно в этом вопросе. Почему он не отсекает практически очевидные ляпы. Потому что система типов в java достаточно простая и компилятор работает с ней слишком прямолинейно. Учитывается только compile-time тип выражения. И при этом тип X обозначает на самом деле "здесь может быть Х или любой его наследник". Так что (чисто теоретически), выражение типа "Bird" в рантайме может иметь значение FlyingBird. Никакой дополнительной проверки вроде "здесь может быть X или любой его наследник до колена Y" в компиляторе нет. Т.е. компилятор "не знает", что в вашем примере "именно bird, а не ее наследник". Нужные проверки при желании реализуются, но это может отказаться сложно и не факт, что принесет большую пользу. Может быть, в pmd или jlint есть подобные проверки, посмотрите. А еще компилятор умеет отлавливать ошибки в случаях, когда точно знает, что наследников не может быть. Сделайте ваш класс Bird final и посмотрите на реакцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 09:21:05 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisЧто мешает компилятору послать нахрен этот код ? Здесь в наглую делается downcast к интерфейсу, который НЕ реализован классом Bird! Реализация компилятора это всегда баланс между временем компиляции и количеством фич и проверок. Раскопай реализации javac и посмотри. То что компилятор отлавливает некоторые ошибки в compile time, это ещё не значит что обязан отлавливать все остальные. Возможно с интерфейсами связан какой-то особый случай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 11:09:34 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisBlazkowiczКомпилятор умеет обнаруживаь ситуации, когда переменная и класс кастинга из совсем разных иерархий .Всё-таки подниму тему. Ибо логику компилятора осилить не в состоянии до сих пор . Вот этот пример: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. - компилируется ОК, но вываливает в рантайме CCE. Что мешает компилятору послать нахрен этот код ? Здесь в наглую делается downcast к интерфейсу, который НЕ реализован классом Bird! Спотыкаюсь на этой фишке уже надцатый раз, блин... :-/ мешает то, что у всех есть общий потомок - Object. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 11:40:44 |
|
||
|
В каких случаях компилятор (не)может увидеть неправильный downcast типов ?
|
|||
|---|---|---|---|
|
#18+
Озверинozzmosisпропущено... Всё-таки подниму тему. Ибо логику компилятора осилить не в состоянии до сих пор . Вот этот пример: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. - компилируется ОК, но вываливает в рантайме CCE. Что мешает компилятору послать нахрен этот код ? Здесь в наглую делается downcast к интерфейсу, который НЕ реализован классом Bird! Спотыкаюсь на этой фишке уже надцатый раз, блин... :-/ *предок мешает то, что у всех есть общий потомок - Object. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.10.2013, 11:41:18 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=206&tid=2128428]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
63ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
| others: | 235ms |
| total: | 399ms |

| 0 / 0 |
