Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / странности с finally / 23 сообщений из 23, страница 1 из 1
22.01.2007, 19:46:38
    #34273415
jdo123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
Код: 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
22.01.2007, 19:53:57
    #34273430
Зашедший
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
jdo123очему так? и почему не бросается exception?
Потому что у тебя return стоит, и программа завершается раньше, чем выводится эксепшн. Убери ретурн - и увидишь потерянное.
...
Рейтинг: 0 / 0
22.01.2007, 19:55:35
    #34273432
Зашедший
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
Хотя почему оно так делает вместо выкидывания исключения из метода - тайна велика есть :)
...
Рейтинг: 0 / 0
22.01.2007, 20:03:36
    #34273447
Зашедший
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
В общем, это идеологическая фишка Сана, но с какой целью была внедрена в таком виде - спрашивать надо у Гослинга. Я лично такое поведение прозрачным не считаю.
З.Ы. Из туториала:
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
22.01.2007, 21:13:33
    #34273544
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
Да, это еще такой есть фокус/загадка. Как в одном методе сделать return 5 раз.
...
Рейтинг: 0 / 0
23.01.2007, 11:50:31
    #34274576
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
ЗашедшийХотя почему оно так делает вместо выкидывания исключения из метода - тайна велика есть :)

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

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

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

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

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

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

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

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

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


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

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

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

Кстати поспрошал дотнетчиков. Говорят return в finally действительно не компиляется. Но зато можно бросить исключение. Которое тоже работает оригинально:
http://www.wintellect.com/Weblogs/DontThrowFromFinally.aspx
...
Рейтинг: 0 / 0
23.01.2007, 15:09:18
    #34275574
wessen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
Код: 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
23.01.2007, 15:09:45
    #34275578
Зашедший
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
странности с finally
wessen Зашедший
Далее, throw тоже очень даже неплохо запретить.


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

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


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

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

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

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

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

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

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


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