powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / странности с finally
23 сообщений из 23, страница 1 из 1
странности с finally
    #34273415
jdo123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
     public   static   void  main(String[] args) {
        System.out.println("F=" + f()); 
    }

     private   int  f() {
         int  i =  0 ;
         try  {
             throw   new  RuntimeException();
          }    catch (Throwable t) {
            System.out.println("Catch " + t);
             throw  t;
        }    finally  {
            System.out.println("Finally!");
             return   7 ;
        }
    }
этот код печатает
Catch java.lang.RuntimeException
Finally!
F=7.
очему так? и почему не бросается exception?
...
Рейтинг: 0 / 0
странности с finally
    #34273430
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jdo123очему так? и почему не бросается exception?
Потому что у тебя return стоит, и программа завершается раньше, чем выводится эксепшн. Убери ретурн - и увидишь потерянное.
...
Рейтинг: 0 / 0
странности с finally
    #34273432
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя почему оно так делает вместо выкидывания исключения из метода - тайна велика есть :)
...
Рейтинг: 0 / 0
странности с finally
    #34273447
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, это идеологическая фишка Сана, но с какой целью была внедрена в таком виде - спрашивать надо у Гослинга. Я лично такое поведение прозрачным не считаю.
З.Ы. Из туториала:
If the finally block does include a transfer of control, then that takes precedence over any transfer of control executed in the try or in an executed catch clause. So for all of the cases listed above, the finally clause would execute, then its transfer of control would take place. Here's one example:
Код: plaintext
1.
2.
3.
4.
5.
6.
    
     try  {
         return   0 ;
    }  finally  {
         return   2 ;
    }

The result of executing this code is that 2 is returned.

Note that this is rather confusing! The moral is that you probably do not want to include transfer-of-control statements in both the try statements and the finally clause, or in both a catch clause and the finally clause.
...
Рейтинг: 0 / 0
странности с finally
    #34273544
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, это еще такой есть фокус/загадка. Как в одном методе сделать return 5 раз.
...
Рейтинг: 0 / 0
странности с finally
    #34274576
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗашедшийХотя почему оно так делает вместо выкидывания исключения из метода - тайна велика есть :)

Какая тут тайна? Есть простое как валенок правило: блок finally выплняется всегда, кроме клинических случаев вроде остановки JVM.
...
Рейтинг: 0 / 0
странности с finally
    #34274662
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz ЗашедшийХотя почему оно так делает вместо выкидывания исключения из метода - тайна велика есть :)

Какая тут тайна? Есть простое как валенок правило: блок finally выплняется всегда, кроме клинических случаев вроде остановки JVM.
Что он выполняется всегда - это понятно. Но нелогично то, что при наличии необработанного исключения блок finally позволяет передать управление и забить на это исключение - что есть преррогатива только блока catch. В итоге Сану приходится делать дополнительное примечание "никогда-никогда не используйте передачу контроля из finally, чтобы избежать потери исключения". И, спрашивается, зачем было делать некую фичу, которую не рекомендуют использовать - вместо того, что просто сделать поведение более логичным?
...
Рейтинг: 0 / 0
странности с finally
    #34274892
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗашедшийЧто он выполняется всегда - это понятно. Но нелогично то, что при наличии необработанного исключения блок finally позволяет передать управление и забить на это исключение - что есть преррогатива только блока catch. В итоге Сану приходится делать дополнительное примечание "никогда-никогда не используйте передачу контроля из finally, чтобы избежать потери исключения". И, спрашивается, зачем было делать некую фичу, которую не рекомендуют использовать - вместо того, что просто сделать поведение более логичным?

Предлашаемое Вами поведение не является более простым или логичным решением. Во-первых по бритве Оккама текущее поведение при прочих равных проще, соответсвенно и реализовано. Если же сделать наоборот. То сразу возникает вопрос а как быть с throw в блоке finally. Ведь тогда исключение из catch выполнится. А из finally по какой-то таинственной причине - нет. Соответсвенно и весь код в блоке finally будет работать как-то не логично и не понятно.
...
Рейтинг: 0 / 0
странности с finally
    #34274997
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz ЗашедшийЧто он выполняется всегда - это понятно. Но нелогично то, что при наличии необработанного исключения блок finally позволяет передать управление и забить на это исключение - что есть преррогатива только блока catch. В итоге Сану приходится делать дополнительное примечание "никогда-никогда не используйте передачу контроля из finally, чтобы избежать потери исключения". И, спрашивается, зачем было делать некую фичу, которую не рекомендуют использовать - вместо того, что просто сделать поведение более логичным?

Предлашаемое Вами поведение не является более простым или логичным решением. Во-первых по бритве Оккама текущее поведение при прочих равных проще, соответсвенно и реализовано. Если же сделать наоборот. То сразу возникает вопрос а как быть с throw в блоке finally. Ведь тогда исключение из catch выполнится. А из finally по какой-то таинственной причине - нет. Соответсвенно и весь код в блоке finally будет работать как-то не логично и не понятно.
Что-то не понял Вашего предложения. Я считаю, что было бы логичным при наличии неперехваченного исключения в finally не передавать управление по return, а выкидывать его. Либо на уровне компилятора запретить использование передачи управления в finally.
...
Рейтинг: 0 / 0
странности с finally
    #34275007
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зашедший wrote:

> И, спрашивается, зачем было делать некую
> фичу, которую не рекомендуют использовать - вместо того, что просто
> сделать поведение более логичным?

Да в Жаве всё такое- наследие Си...
Например доступность по записи x при таком объявлении
public int x;

--
Алексей
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
странности с finally
    #34275052
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗашедшийЧто-то не понял Вашего предложения. Я считаю, что было бы логичным при наличии неперехваченного исключения в finally не передавать управление по return, а выкидывать его.

Ну, хорошо а как ты себе это представляешь? Выполняется код который в блоке finally, а потом там где находится return происходит прокидывания исключения, которое было создано выше? Это называется логично?

ЗашедшийЛибо на уровне компилятора запретить использование передачи управления в finally.
То есть запретить там как return так и throw вообще? Это тоже по-твоему логично?
...
Рейтинг: 0 / 0
странности с finally
    #34275157
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczТо есть запретить там как return так и throw вообще? Это тоже по-твоему логично?
Вполне логично. Return может скрыть необработанные исключения, что не есть хорошо. К тому же я себе слабо представляю, с какой целью надо использовать return в finally. То есть - когда такое решение будет лучше, чем возврат из try или catch. Можете попробовать привести пример такого решения. Далее, throw тоже очень даже неплохо запретить, потому что блок finally предназначен только для гарантированного освобождения ресурсов, а никак не для обработки исключений. Надо заменить исключение - используйте catch, кинуть исключение - try.
...
Рейтинг: 0 / 0
странности с finally
    #34275531
wessen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зашедший
Далее, throw тоже очень даже неплохо запретить.


А если я захочу в блоке fynally сделать throw и там же его поймать? Это тоже не логично?
...
Рейтинг: 0 / 0
странности с finally
    #34275552
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зашедшийпотому что блок finally предназначен только для гарантированного освобождения ресурсов, а никак не для обработки исключений. Надо заменить исключение - используйте catch, кинуть исключение - try.

Начало понятно, но завершить мысль у Вас не получается. Вопрос. С какой-такой стати мне должно быть запрещено пробрасывать исключения в блоке finally??? Поймал одно исключение, пытаюсь закрыть ресурс, происходит ошибка закрытия ресурса, и теперь что? Я обязан обработку этого исключения всегда в finally делать? А как мне сообщить о нем другим уровням приложения?

В общем, ИМХО, это не самое лучше место для поиска того что мы тут "умнее" команды Sun. Текущее поведение очень логично и нормальных альтернатив ему нет.

Кстати поспрошал дотнетчиков. Говорят return в finally действительно не компиляется. Но зато можно бросить исключение. Которое тоже работает оригинально:
http://www.wintellect.com/Weblogs/DontThrowFromFinally.aspx
...
Рейтинг: 0 / 0
странности с finally
    #34275574
wessen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
     public   static   void  main( String[] args ) {
        System.out.println( "F=" + f() );
    }

     private   static   int  f() {
         int  i =  0 ;
         try  {
            // throw new RuntimeException("1");
             return   25 ;
        }  catch  ( Throwable t ) {
            System.out.println( "Catch " + t );
             throw  t;
        }  finally  {
            System.out.println( "Finally!" );
             throw   new  RuntimeException( "2" );
            //return 7;
        }
    }

вывод:
Finally!
Catch java.lang.RuntimeException: 2
Finally!
Exception in thread "main" java.lang.RuntimeException: 2
at ru.labma.sti4ei.mac.ipsm.test.Test.f(Test.java:38)
at ru.labma.sti4ei.mac.ipsm.test.Test.main(Test.java:25)

без запуска никогда бы не додумался, что такой вывод получится.
...
Рейтинг: 0 / 0
странности с finally
    #34275578
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wessen Зашедший
Далее, throw тоже очень даже неплохо запретить.


А если я захочу в блоке fynally сделать throw и там же его поймать? Это тоже не логично?
Use nested try...catch.
...
Рейтинг: 0 / 0
странности с finally
    #34275595
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНачало понятно, но завершить мысль у Вас не получается. Вопрос. С какой-такой стати мне должно быть запрещено пробрасывать исключения в блоке finally??? Поймал одно исключение, пытаюсь закрыть ресурс, происходит ошибка закрытия ресурса, и теперь что? Я обязан обработку этого исключения всегда в finally делать? А как мне сообщить о нем другим уровням приложения?
Тут с throw как ни крути, все равно нормального поведения не сделать. Собственно, я имел в виду запретить прямое выкидывание исключений, только если их возвращают вызываемые методы.
З.Ы. Вот wessen привел чУдный пример того, как поведение метода становится слабопредсказуемым...
...
Рейтинг: 0 / 0
странности с finally
    #34275628
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗашедшийЗ.Ы. Вот wessen привел чУдный пример того, как поведение метода становится слабопредсказуемым...

Да где же оно не предсказуемое? Ночью меня разбудить и такой код показать я вам скажу что будет. А все потому что это поведение описывается одним простым правилом которое так легко запомнить.
...
Рейтинг: 0 / 0
странности с finally
    #34275629
wessen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зашедший wessen Зашедший
Далее, throw тоже очень даже неплохо запретить.


А если я захочу в блоке fynally сделать throw и там же его поймать? Это тоже не логично?
Use nested try...catch.

вот тут можно подумать, как проще сделать, так как сейчас, или учитывать всевозможные варианты: throw в finally без catch, return в методе, который вызывается в блоке finally...
...
Рейтинг: 0 / 0
странности с finally
    #34275844
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz ЗашедшийЗ.Ы. Вот wessen привел чУдный пример того, как поведение метода становится слабопредсказуемым...

Да где же оно не предсказуемое? Ночью меня разбудить и такой код показать я вам скажу что будет. А все потому что это поведение описывается одним простым правилом которое так легко запомнить.
Выполнение секции finally? Обяснить такое поведение можно, но выглядит оно несколько неочевидно. Сугубое имхо.
...
Рейтинг: 0 / 0
странности с finally
    #34275846
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Двукратное выполнение..."
...
Рейтинг: 0 / 0
странности с finally
    #34275897
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗашедшийВыполнение секции finally? Обяснить такое поведение можно, но выглядит оно несколько неочевидно. Сугубое имхо.

Вы таки не знакомы с принципом бритвы Оккама? Это решение при прочих равных самое простое.
Почему при прочих равных? Потому что все альтернативы так же будут иметь подобные странности, но при этом их поведение будет описать сложнее. А значит и понять тоже.

Хотя в одном я могу согласить. return в finally можно было бы и запретить. Только сейчас подобные изменения в Java невозможны из-за обратной совместимости, которой в Sun так гордятся. Максимум warning новый моэно добавить.
...
Рейтинг: 0 / 0
странности с finally
    #34276023
Зашедший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz ЗашедшийВыполнение секции finally? Обяснить такое поведение можно, но выглядит оно несколько неочевидно. Сугубое имхо.

Вы таки не знакомы с принципом бритвы Оккама? Это решение при прочих равных самое простое.
Почему при прочих равных? Потому что все альтернативы так же будут иметь подобные странности, но при этом их поведение будет описать сложнее. А значит и понять тоже.

Хотя в одном я могу согласить. return в finally можно было бы и запретить. Только сейчас подобные изменения в Java невозможны из-за обратной совместимости, которой в Sun так гордятся. Максимум warning новый моэно добавить.
Сей принцип преподают на первом году любого вуза, в составе курса философии. Надо очень постараться, чтобы не знать. И - да, я не считаю подобное поведение самым очевидным. Собственно, с ненужности в finally использования return разговор и начался. Вот насчет запрета throw я погорячился, не спорю. И кроме того, двухкратное выполнение секции тоже не слишко однозначно, логически было бы яснее, если при возникновении в завершающей секции метода finally это исключение просто будет пробрасываться наружу.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / странности с finally
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]