Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];

Вниз

Прослушал тут курсы C#...   Найти похожие ветки 

 
Layner ©   (2006-03-20 11:02) [0]

Обязали с предприятия, записался на C#. Узнал не сказать чтобы много, но есть много интересного. Например любую прогу, написанную на C# легко можно вскрыть на исх. коды например с помощью программы Рефлектор... т.е. пишем программу, компилируем, запускаем Рефлектор (ищется в инете легко), открываем через нее exe, оп ля, и все как на ладони.. :) Причем читается на любой язык, т.е. написали на C#, а коды можно читать как на BASIC.#, так и для Delphi.Net, и ещё для 2х языков...
Т.е. защиты программ практически никакой, препод подтвердил.
Есть конечно программы 3х контор, которые меняют названия переменных в нечитаемые, но это уже слабая заглушка.
Что ещё... Не удобно же все таки с этим фреймворком, у меня программа, скомпилированная на курсах вообще отказывается запускаться на ноутбуке... Слышал краем уха, что фрейморк на клиентах должен быть той же версии, где и компилировалась программа, причем препод сказал, не ниже и не выше :) Сам не проверял... Этож как с клиентами работать, если распространять программу через инет...

И еще много аналогичных не понятных пока моментов.

Говорят, минусы компенсируют плюсы, типа 18тыс классов созданные ребятами Microsoft пойдут на пользу всем любителям быстрой разработки программ, т.к. в них реализованно почти ВСЕ, что требуется 99% программистам...

Delphi вообще предписали медленную смерть, ибо все толковые из борланда перетекают в майкросовт, Delphi вообще в серьез никто не воспринимает.

Мое мнение, лучше Delphi ещё не видел, как писал на ней, так и буду писать.


 
Layner ©   (2006-03-20 11:04) [1]

В заключении значит, в чем т.е. ещё раз и убедился.


 
Dok_3D ©   (2006-03-20 11:08) [2]

2 Layner ©   (20.03.06 11:02)  
Мое мнение, лучше Delphi ещё не видел, как писал на ней, так и буду писать.

От тюрьмЫ и от сумЫ, как говорится ...


 
Layner ©   (2006-03-20 11:15) [3]

Ну на пару лет ещё работаю как и работал. Хвалят студию 2005, в ней редактор кода удобнее, ее может поставлю, если сумею достать, а работать на .Net если и планирую сейчас, то только с XML файлами. А дальше посмотрим. Не отвергаю конечно... Но родная delphi среда ближе и приятнее. ^)


 
Игорь Шевченко ©   (2006-03-20 11:27) [4]


> типа 18тыс классов созданные ребятами Microsoft пойдут на
> пользу всем любителям быстрой разработки программ, т.к.
> в них реализованно почти ВСЕ, что требуется 99% программистам.
> ..


Каждому программисту придается резиновая голова, чтобы запомнить, какой из 18 тысяч классов что делает.


 
k2 ©   (2006-03-20 11:30) [5]

а можно две в одни руки? :) надо позарез


 
ZeroDivide ©   (2006-03-20 11:53) [6]

Эт хорошо что на курсы посылали... я последний раз 3 года назад на курсах был :(


 
Alkid ©   (2006-03-20 11:58) [7]


> аждому программисту придается резиновая голова, чтобы запомнить,
>  какой из 18 тысяч классов что делает.

А разе голова для простого программирования для Windows или просто
на Delphi голова не должна много помнить? :)


 
ilya39 ©   (2006-03-20 12:02) [8]


> Прослушал тут курсы C#...
> Layner ©   (20.03.06 11:02)

Очередная параноя на тему: "да зачем этот Net придумали, да зачем это надо..." Сколько можно?


 
Карелин Артем ©   (2006-03-20 12:20) [9]


> Игорь Шевченко ©   (20.03.06 11:27) [4]

Так пространства имен очень удобно структурируют всю эту кучу.

Мне очень нравится 2005 студия. Но распространять через инет программы на фреймворке жестко, особенно писанные под 2,0 фреймворк....


 
Alkid ©   (2006-03-20 12:26) [10]


> Очередная параноя на тему: "да зачем этот Net придумали,
>  да зачем это надо..." Сколько можно?

ИМХО появление ЛЮБОЙ достаточно радикально новой технологии будет сопровождаться такими комментариями. Это неизбежно. :)
Другое дело, самому .NET эти восклицания уже несколько до фени, он уже
успешно занимает свой кусок рынка.


 
ilya39 ©   (2006-03-20 12:30) [11]


> достаточно радикально новой технологии

Осторожней, сейчас начнется: "да это все было в Java и т.д." :)


> Другое дело, самому .NET эти восклицания уже несколько до
> фени, он уже
> успешно занимает свой кусок рынка.

Вот тут полностью согласен!


 
Alkid ©   (2006-03-20 12:31) [12]


> торожней, сейчас начнется: "да это все было в Java и т.д.
> " :)

И в Дельфи было :)
Короче, сейчас скажут, что .NET - глубоко вторичен и в нём мало креатива ;)


 
iZEN ©   (2006-03-20 13:59) [13]

>Layner ©   (20.03.06 11:02)
>Например любую прогу, написанную на C# легко можно вскрыть на исх. коды например с помощью программы Рефлектор... т.е. пишем программу, компилируем, запускаем Рефлектор (ищется в инете легко), открываем через нее exe, оп ля, и все как на ладони..

Это было в 1998 году в JBuilder 2.0, если не раньше. Любой java-класс можно было на лету (в дереве папок файловой системы) декомпилировать в среде и смотреть его код (в редакторе кода). Обфускаторы, конечно, порядком запутывали двоичный код, но на то они и обфускаторы. Ведь так?

А тут мы открыли для себя через семь лет это снова... :))
Забавненько.

>ilya39 ©   (20.03.06 12:30) [11]
>> достаточно радикально новой технологии
>Осторожней, сейчас начнется: "да это все было в Java и т.д." :)

В Smalltalk это уже 20 лет есть.

Alkid ©   (20.03.06 12:31) [12]
>И в Дельфи было :)

Кохда?


 
Eraser ©   (2006-03-20 14:03) [14]


> Карелин Артем ©   (20.03.06 12:20) [9]


> Мне очень нравится 2005 студия.

а почему не 2006? гораздо лучше по-моему....


 
Карелин Артем ©   (2006-03-20 14:35) [15]


> Eraser ©   (20.03.06 14:03) [14]

Ты знаешь, вчера был на рынке... Там почему-то нет уже вышедшей 2006 дельфи, но вовсю продается 2006 студия, хотя официальная инфа у меня что последние 2006 дельфи и 2005 студия :)))


 
Alkid ©   (2006-03-20 14:37) [16]


> Кохда?

Да не, про рефлекшн и супер-декомпиляцию - такого в дельфи не было.
Я просто про то, что в .NET можество идей и подходов из дельфи.


 
iZEN ©   (2006-03-20 15:23) [17]

>Alkid ©   (20.03.06 14:37) [16]
>Да не, про рефлекшн и супер-декомпиляцию - такого в дельфи не было.
>Я просто про то, что в .NET можество идей и подходов из дельфи.

Конечно-конечно.
Много подходов.
Один из таких подходов, например, - отказ от checked exception"s.
Чувство такое, что разработчики точки-нэт просто наплевали на задачу эффективной работы с исключениями на уровне компилятора. ;)


 
_inic   (2006-03-20 15:30) [18]

[0]
> фрейморк на клиентах должен быть той же версии, где и компилировалась > программа

вообще-то вроде в манифесте прописывается мин. версия или конкретная

ИМХО, препод неправильно выразился ?


 
Карелин Артем ©   (2006-03-20 15:36) [19]

Во фреймворке 1.1 была небольшая бага с System.Windows.Forms.DateTimePicker.
В фреймворке 2.0 ее устранили, введя другую багу...


 
Карелин Артем ©   (2006-03-20 16:17) [20]


> iZEN ©   (20.03.06 13:59) [13]

Не считай меня ламером, но я не могу найти Рефлектор в нете. Может укажешь приблизительное направление???


 
Рамиль ©   (2006-03-20 16:24) [21]


> Карелин Артем ©   (20.03.06 16:17) [20]

Наверное вот это
http://www.yandex.ru/yandsearch?text=%E4%E5%EA%EE%EC%EF%E8%EB%E8%F0%EE%E2%E0%ED%E8%E5+.NET+Reflector&stype=www


 
Alkid ©   (2006-03-20 16:25) [22]


> Конечно-конечно.
> Много подходов.
> Один из таких подходов, например, - отказ от checked exception"s.

Поясни фишку. От каких они там экспешнов отказались?


 
iZEN ©   (2006-03-20 16:56) [23]

>Alkid ©   (20.03.06 16:25) [22]
>> Один из таких подходов, например, - отказ от checked exception"s.
>Поясни фишку. От каких они там экспешнов отказались?

От проверяемыхchecked.
В сигнатуре метода вызываемого кода можно задать (throws <список>) те проверяемые исключения, которые он бросает вызывающему коду в случае исключительной ситуации. Компилятор на этапе компиляции должен проверить, обрабатывается ли такие исключения в вызывающем коде (try/catch) или повторно бросаются (throws <то же список> в сигнатуре вызывающего метода), если не обрабатывается и не бросаются (throw) — компилятор говорит, что компиляция невозможна, ошибка времени компиляции.

Ну так в C# забили на эту фишку толстый болт от арбалета и приняли идею Delphi: все исключения считать непроверяемыми — Unchecked Exception"s.


 
iZEN ©   (2006-03-20 16:59) [24]

Карелин Артем ©   (20.03.06 16:17) [20], понятия не имею про Рефлектор. Спросите кого-нибудь более сведующего.


 
DiamondShark ©   (2006-03-20 17:39) [25]


> iZEN ©   (20.03.06 16:56) [23]

А зачем лишние сущности плодить?


 
Sandman25 ©   (2006-03-20 17:41) [26]

DiamondShark ©   (20.03.06 17:39) [25]

А зачем лишние сущности плодить?

Это ты про объекты?


 
DiamondShark ©   (2006-03-20 17:54) [27]


> Sandman25 ©   (20.03.06 17:41) [26]

Это я про checked exception"s


 
Sandman25 ©   (2006-03-20 17:58) [28]

DiamondShark ©   (20.03.06 17:54) [27]

Это я про checked exception"s

Неужели иронию не понял? Стареем.
Checked Exception - удобная штука, особенно при использовании собственных классов исключений.


 
DiamondShark ©   (2006-03-20 18:04) [29]


> Sandman25 ©   (20.03.06 17:58) [28]

Вполне возможно, что я чего-то не улавливаю.
Можно простенький (или сложненький, если просто не получится) примерчик, так, чтоб было очевидно, что без них тут было бы сильно неудобно.

Я действительно хочу понять, в чём там соль...


 
Layner ©   (2006-03-20 18:42) [30]

.NET Reflector 4.0

http://www.aisto.com/roeder/dotnet
http://workspaces.gotdotnet.com/reflector

Я смотрел в целом "глазами шароварщика", т.е. можно ли его прикрутить под опред. мои цели. Как оказалось, можно, но код открыт. Отсюда какая либа защита не катит.


 
iZEN ©   (2006-03-20 19:48) [31]

DiamondShark ©   (20.03.06 18:04) [29]
> Sandman25 ©   (20.03.06 17:58) [28]
>Вполне возможно, что я чего-то не улавливаю.
>Можно простенький (или сложненький, если просто не получится) примерчик, так, чтоб было очевидно, что без них тут было бы сильно неудобно.
>Я действительно хочу понять, в чём там соль...

Ну это же фундамент контрактного программирования. Проверяемые исключения являются одним из механизмов сигнализации (научный термин) на этапе компиляции, а не выполнения.

Delphi и C# могут просигнализировать о необработанной ошибке в программе только тогда, когда эта ошибка возникает в работающем коде (Unchecked Exception) — скорее всего будет Access Violation, и программа завершится крахом.

Java и Eiffel имеют две сигнальные системы:
* Unchecked Exception"s, работающие в рантайме,
и
* Сhecked Exception"s, выполняющие свои функции не только в рантайме, но и на этапе компиляции — за их семантикой следит компилятор.

В надёжной системе обычно присутствует подсистема восстановления после сбоев, но ей достаточно знать о Unchecked Exception"s (непроверяемые исключения, например, распространены в EJB). На этапе компиляции небольших программ со сторонними бинарными библиотеками можно гарантировать построение надёжного кода только при наличии Сhecked Exception"s, так как доступ к документации и тем более к исходникам библиотек часто ограничен.


 
Ломброзо ©   (2006-03-20 20:43) [32]

дадад
public void OpenFile(String fileName)
 throws InvalidPathException,
 FileNotExistsException,
 FileIsLockedException,
 AccessDeniedException,
 IOException,
 HDDNotFoundException,
 OSException...
{

}

и на всё это хозяйство надо повесить по кэтчу, что под силу только представителям педантичной нации типа ипонцев. Прочих мало интесует, почему не окрывается файл. Не открылся - ну и хрен с ним.


 
Ломброзо ©   (2006-03-20 20:46) [33]

Я к тому, что рано или поздно код, использующий мегаконтрактные библиотеки, начинает изобиловать конструкциями типа
public void DoOpenFile throws Throwable
{
 OpenFile(..);
}

или

try
{
  OpenFile(...);
}
catch (Throwable e)
{
  throw new RuntimeException(e);
}


 
DiamondShark ©   (2006-03-20 21:17) [34]


> iZEN ©   (20.03.06 19:48) [31]

Послушайте, впасть в транс от мантры, вроде: "это фундамент чего-то-там-написанного-жирным-шрифтом" я могу самостоятельно. Определение я где-то слышал. Именно исходя из определения я посчитал эту фичу приносящей много возни и около нуля эффекта. Именно поэтому я просил пример. Практический. Тем более, что уверяли, что бывают случаи, где это очень удобно.

Пока единственный более-менее практически значимый момент -- это в отсутствии документации узнать из метаданных, какие исключения может кидать метод.
Извините, но это слишком слабый плюс по сравнению с привносимыми неудобствами.


 
Геро   (2006-03-20 21:18) [35]

Как и все новое, .NET переживет время недоверия, время взлета, а затем просто станет скучной обыденностью.


 
iZEN ©   (2006-03-20 21:30) [36]

>Ломброзо ©   (20.03.06 20:46) [33]
>Я к тому, что рано или поздно код, использующий мегаконтрактные библиотеки, начинает изобиловать конструкциями типа
>public void DoOpenFile throws Throwable...

Не будет изобиловать, уверяю Вас. Одиннадцать лет показали, что такого не случилось.


 
iZEN ©   (2006-03-20 21:37) [37]

DiamondShark ©   (20.03.06 21:17) [34], ещё раз повторяю, что этот механизм важен программистам, его использующим. Кто его не использует, он нафик не нужен.

Необработанное исключение (всегда Unchecked Exception) в Delphi приводит к системному сообщению и/или к остановке выполнения программы. И это встречается очень часто. В половине случаев такое положение связано с неучтённой семантикой вызова библиотечного метода (забывчивость программиста, недостаточная документированность вызываемого кода и другие мантры, всё - действие ЧЕЛОВЕЧЕСКОГО_ФАКТОРА). Это можно исправить на этапе компиляции, если есть возможность использовать механизм Checked Exception"s. В Delphi и C# такого механизма нет. И живут же люди...


 
Kerk ©   (2006-03-20 21:43) [38]

Alkid ©   (20.03.06 12:31) [12]
Короче, сейчас скажут, что .NET - глубоко вторичен и в нём мало креатива ;)


Года полтора назад пришлось поработать в .NET с сишником.. многие вещи, от которых он был там в восторге, я после Delphi воспринимал как данность.


 
Piter ©   (2006-03-20 22:01) [39]

Карелин Артем ©   (20.03.06 12:20) [9]
Мне очень нравится 2005 студия. Но распространять через инет программы на фреймворке жестко


пиши на C++, никто же не запрещает.


 
iZEN ©   (2006-03-20 22:21) [40]

>Ломброзо ©   (20.03.06 20:43) [32]
>дадад
>public void OpenFile(String fileName)
> throws InvalidPathException,
> FileNotExistsException,
> FileIsLockedException,
> AccessDeniedException,
> IOException,
> HDDNotFoundException,
> OSException...
>{
>
>}
>
>и на всё это хозяйство надо повесить по кэтчу, что под силу только представителям педантичной нации типа ипонцев.

Несовсем.
Достаточно только те, которые не обрабатываются внутри этого метода.

Если не хотим обрабатывать конкретно в этом методе (что, действительно, бывает не всегда нужно), то можно объявить о бросании их общего предка (иерархия наследования Exception"s предполагает, как правило, разумное определение связей родитель-потомки), так как в большинстве случаев гораздо эффективнее вести обработку типичных исключительных ситуаций в "верхних" слоях вызывающего кода, а не на самом нижнем слое в вызываемом коде, где доступна слишком детальная информация, чтобы её обрабатывать (и тратить вычислительные ресурсы на это).

>Прочих мало интесует, почему не окрывается файл. Не открылся - ну и хрен с ним.
Бросайте их общего предка.

Грамотный дизайн кода, как всегда, решает.


 
Карелин Артем ©   (2006-03-21 05:41) [41]


> Piter ©   (20.03.06 22:01) [39]

Для широкой публики у меня есть Дельфи 5, которую менять на другие версии не собираюсь. Хотя вчера серьезно думал о переходе на бесплатную версию студии 2005.
На работе уже перешли на студию 2005.


 
Тульский ©   (2006-03-21 10:47) [42]


> Например любую прогу, написанную на C# легко можно вскрыть
> на исх. коды например с помощью программы Рефлектор... т.
> е. пишем программу, компилируем, запускаем Рефлектор (ищется
> в инете легко), открываем через нее exe, оп ля, и все как
> на ладони.. :) Причем читается на любой язык, т.е. написали
> на C#, а коды можно читать как на BASIC.#, так и для Delphi.
> Net, и ещё для 2х языков...

Так это же замечательно!


 
GrayFace ©   (2006-03-21 11:12) [43]

> iZEN ©   (20.03.06 21:37) [37]
> Необработанное исключение (всегда Unchecked Exception) в
> Delphi приводит к системному сообщению и/или к остановке
> выполнения программы. И это встречается очень часто. В половине
> случаев такое положение связано с неучтённой семантикой
> вызова библиотечного метода (забывчивость программиста,
> недостаточная документированность вызываемого кода и другие
> мантры, всё - действие ЧЕЛОВЕЧЕСКОГО_ФАКТОРА).

Сколько ни программировал - ни разу "половины случаев" не встречал. По-моему, самое частое исключение - это Access Violation.


 
iZEN ©   (2006-03-21 12:20) [44]

>GrayFace ©   (21.03.06 11:12) [43]
>Сколько ни программировал - ни разу "половины случаев" не встречал. >По-моему, самое частое исключение - это Access Violation.
Ну и что, по-вашему, послужило причиной Access Violation? Скорее всего не знаете. А это рантайм-исключение (Unchecked), вызванное обращением к неразмеченной области памяти (скорее всего Null Pointer Exception). Но оно слишком общее, чтобы судить о контексте выполнения в работающей системе. Кстати, под него очень часто подпадают необработанные исключения, которые возникают в библиотечных методах — в тех самых "малозаметных узких местах". Вы их не видите, потому что не обрабатываете там, где следовало бы просто из-за недостатка информации о реальной сигнатуре метода (когда вызываемый метод бросает явное или неявное исключение). Исполняющая система Delphi ловит "наверху" всё, по определению, вот и выдаёт слишком общее сообщение об ошибке.

В отладочном режиме, когда среда следит за такими исключениями, всё это можно проследить. Но всегда во время работы приложения. Что вы будете делать, когда приложение уже установлено на местах? Советовать пользователю: "не пользоваться определённой кнопкой, так как это может привести к непредсказуемым результатам с Access Violation"? И, может быть, "отозвать" приложение на повторную отладку и доводку? И снова проводить тесты качества...

Увы, в Delphi и C# это — единственный путь подтверждения корректности программы.

Я не говорю, что проверка компилятора на этапе сборки есть альтернатива, я говорю, что Checked Exception"s являются дополнительной проверкой корректности, "работающей" без необходимости запуска приложения на выполнение. Такой же важной составляющей надёжного ПО, что и первая сигнальная система на основе Uncheked Exception"s.


 
Игорь Шевченко ©   (2006-03-21 12:28) [45]


> В отладочном режиме, когда среда следит за такими исключениями,
>  всё это можно проследить. Но всегда во время работы приложения.
>  Что вы будете делать, когда приложение уже установлено
> на местах?


А что, тестирование уже отменили ?


 
Карелин Артем ©   (2006-03-21 12:58) [46]


> iZEN ©   (21.03.06 12:20) [44]

А что, Null pointer exception в яве проявляется реже чем AV??


 
KSergey ©   (2006-03-21 16:07) [47]

Я, вероятно, не очень в курсе, но такое навязчивое впчатление, что вы говорите про С++.
Так может все дело в том, что в C++ (самом языке) нет декларированного общего предка для класса исключений? От того и нужны все эти пляски с чекалкой?
В дельфи я всегда могу написать

begin
  try
   ...
  except Exception e
   ...
  end;
end.


и какой тут чекер что проверит? Очевидно, что кидаются только Exception... от того, видимо, просто отпал необходимость этих чеканий на этапе компиляции?


 
Sandman25 ©   (2006-03-21 17:01) [48]

Например:

public void Login(...) throws WrongLoginParamsException, UserIsBlockedException, IPAccessDeniedException...

Поставщик метода тем самым описывает, какие могут быть ситуации, и вызыващий код может анализировать ситуацию без искусственых механизмов типа кода или текста сообщения.


 
Petr V. Abramov ©   (2006-03-21 17:06) [49]

> Sandman25 ©   (21.03.06 17:01) [48]
 А кто мешает анализировать на основе класса исклчения?
или поподробней, если не сложно... :)


 
pasha_golub ©   (2006-03-21 17:12) [50]

Нифига не могу понять суть checked exceptions. Вернее не суть, а "высшую суть", их так сказать божественное начало. Для чего они нам спущены были? Я с успехом во время ран-тайма все ловлю.


> Что вы будете делать, когда приложение уже установлено на
> местах?

EurekaLog.com forever !!! С помощью этой ляли такие "висяки" находил, шо страх и ужос. Под висяками я понимаю, как раз эти пресловутые, AV.


 
Sandman25 ©   (2006-03-21 17:16) [51]

Petr V. Abramov ©   (21.03.06 17:06) [49]

Никто не мешает, это и есть класс исключения :) Только конкретный класс исключения прописан не в комментариях к методу, а в сигнатуре самого метода, так чтобы задействовать компилятор.


 
Sandman25 ©   (2006-03-21 17:18) [52]

pasha_golub ©   (21.03.06 17:12) [50]

Я с успехом во время ран-тайма все ловлю.

Ловите на здоровье. Потом где-то добавится новый Exception, где-то уберется старый, и Вам придется ручками бегать по модулям и проверять, чего и где. На java же будет выдан compile-time error.


 
Petr V. Abramov ©   (2006-03-21 17:20) [53]

> Sandman25 ©   (21.03.06 17:16) [51]
 Ну это-то идея понятная ( а значит, хорошая :)
Но причем здесь обязательная обработка-то? Может, меня устраивает стандартная реакция на UserIsBlockedException


 
Игорь Шевченко ©   (2006-03-21 17:24) [54]


> Ловите на здоровье. Потом где-то добавится новый Exception,
>  где-то уберется старый, и Вам придется ручками бегать по
> модулям и проверять, чего и где. На java же будет выдан
> compile-time error


Это конечно все хорошо. Но Exception это вроде исключительная ситуация, поэтому народ в моем лице не совсем понимает, зачем ее отлавливать на уровне компиляции...
Пример бы разумный, где бы такое могло с успехом пригодиться, не помешал бы.


 
Sandman25 ©   (2006-03-21 17:25) [55]

Petr V. Abramov ©   (21.03.06 17:20) [53]

Если устраивает, так и напишите в своем методе throws UserIsBlockedException, чтобы те, кто использует Ваш метод знали, что UserIsBlockedException Вы не обрабатываете, а передаете "выше".


 
Petr V. Abramov ©   (2006-03-21 17:29) [56]

> Sandman25 ©   (21.03.06 17:25) [55]
 То есть идея в том, что если в сигнатуре public void Login(...)  добавится новый exception, который "throws", то поплывут все методы, которые Login используют, и, хочешь, не хочешь, придется задуматься, "устраивает" стандартное или нет?


 
Sandman25 ©   (2006-03-21 17:34) [57]

Игорь Шевченко ©   (21.03.06 17:24) [54]

Но Exception это вроде исключительная ситуация, поэтому народ в моем лице не совсем понимает, зачем ее отлавливать на уровне компиляции...

Чтобы убедиться, что ничего не пропустили. Либо перехватываете, либо говорите всему миру, что не перехватываете и пускай они сами разбираются :) Никаких недомолвок и неактуальных документаций. Обычно проблемы в работе ПО связаны как раз с исключительными ситуациями.


 
Sandman25 ©   (2006-03-21 17:35) [58]

Petr V. Abramov ©   (21.03.06 17:29) [56]

То есть идея в том, что если в сигнатуре public void Login(...)  добавится новый exception, который "throws", то поплывут все методы, которые Login используют, и, хочешь, не хочешь, придется задуматься, "устраивает" стандартное или нет?

Верно. Не будет ситуации, что метод изменили, а клиент об этом даже не знает, и поэтому некорректно работает.


 
Sandman25 ©   (2006-03-21 17:38) [59]

Petr V. Abramov ©   (21.03.06 17:29) [56]

Конечно, елси клиент throws Thorwable, как тут писали некоторые, то толку от идеи никакой, только вред один. Ну так это проблемы тех, кто так пишет.
try
...
except
end
тоже не слишком полезен :)


 
Petr V. Abramov ©   (2006-03-21 17:39) [60]

> Sandman25 ©   (21.03.06 17:35) [58]
 Сколько возможностей для мелкого хулиганства в большом проекте :)
Добавил в throws какого-нить очень популярного, но изнутри запутанного метода, и в отпуск на недельку :)
 Но что-то в этой идее есть


 
Игорь Шевченко ©   (2006-03-21 17:45) [61]

Sandman25 ©   (21.03.06 17:34) [57]


> Чтобы убедиться, что ничего не пропустили. Либо перехватываете,
>  либо говорите всему миру, что не перехватываете и пускай
> они сами разбираются :)


Я извиняюсь, но из кода


> public void Login(...) throws WrongLoginParamsException,
>  UserIsBlockedException, IPAccessDeniedException


следует, что как раз наоборот, я говорю всему миру, что я могу выдавать наружу exceptions определенного типа. А о перехвате в объявлении вроде не упоминается. Или я что-то не так понял ?

Sandman25 ©   (21.03.06 17:38) [59]


> try
> ...
> except
> end
> тоже не слишком полезен :)


Да, за такое обычно надо долго и больно быть по голове, если только рядом не написан подробный комментарий, зачем такая конструкция была примененя.


 
Sandman25 ©   (2006-03-21 17:56) [62]

Я смотрю, мне надо было не лениться и сразу написать всю цепочку :(

Допустим есть стандартный класс

public class TStandardDataBase..{
public void Login(...) throws WrongLoginParamsException, UserIsBlockedException, IPAccessDeniedException;
}

и собственный класс
public TMyClass ..{
 private TStandardDataBase myDataBase;
 public void myLogin throws UserIsBlockedException, IPAccessDeniedException{
   ...
   try
   {
   myDataBase.Login;
   }
   catch (WrongLoginParamsException e)
   {
     logger.WriteCriticalError(e);
     System.exit(-1);
   }
 }
}

Таким образом, хотя Login и генерирует WrongLoginParamsException, обрабатывать его в коде, который вызывает myLogin(), не надо:

try
{
 myClass(..)
}
catch (UserIsBlockedException e)
{
...
}
catch (IPAccessDeniedException e)
{
...
}


 
Sandman25 ©   (2006-03-21 17:58) [63]

Пример, конечно, надуманный, потому как я не могу выдавать реальные примеры из собственной практики.


 
KSergey ©   (2006-03-21 18:01) [64]

> Sandman25 ©   (21.03.06 17:25) [55]
> Если устраивает, так и напишите в своем методе throws UserIsBlockedException,
>  чтобы те, кто использует Ваш метод знали, что UserIsBlockedException
> Вы не обрабатываете, а передаете "выше".

Во, видел я такой код (с++).
Что мне из него стало совершенно не ясно:
положим, я в своем новом мега супер методе вызываю 10 других методов 5 объектов. Те, в свою очередь, еще чео-то тама унутрях себя вызывают. Все, как водится, норовят кинуть исключения всякие. Теперь получается так: я должен оббежать все 10 методов - и выяснить: а какого же они могут выкинуть фердебобеля? Ага, до фига всего. Так, значит или крутить обработку тут, или все оту фигню прописывать у себя в сигнатуре.... Короче капец полный получается...

Т.е. вероятно идея хрошая, если изначально все правильно строить, но учитывая, что очень многие методы с удовольствием бы накидали кучу исключений, но ни в коем разе не хотят разбираться что тама сломалось унутрях (ну не вышло - ну и хрен с ним, откатили) - то вот эти копирования сигнатур шибко напрягают, признаюсь. Тайный смысл пока так и не понял....


 
Игорь Шевченко ©   (2006-03-21 18:10) [65]


> Тайный смысл пока так и не понял....


Присоединяюсь к предыдущему оратору.


> Допустим есть стандартный класс
>
> public class TStandardDataBase..{
> public void Login(...) throws WrongLoginParamsException,
>  UserIsBlockedException, IPAccessDeniedException;
> }
>
> и собственный класс
> public TMyClass ..{
>  private TStandardDataBase myDataBase;
>  public void myLogin throws UserIsBlockedException, IPAccessDeniedException{
>    ...
>    try
>    {
>    myDataBase.Login;
>    }
>    catch (WrongLoginParamsException e)
>    {
>      logger.WriteCriticalError(e);
>      System.exit(-1);
>    }
>  }
> }
>
> Таким образом, хотя Login и генерирует WrongLoginParamsException,
>  обрабатывать его в коде, который вызывает myLogin(), не
> надо:


Я извиняюсь за оверквотинг, но если из-за кривости рук программиста, написавшего Login(...) из него выскочит какой-то другой Exception из неуказанных в сигнатуре метода, то что произойдет и как мне поможет компилятор ?


 
DiamondShark ©   (2006-03-21 18:16) [66]

Кстати, а что произойдёт, если метод всё-таки выбросит недекларированное исключение?
ну вот например метод, вроде такого

int MyCrazzyMethod(int a, int b)
{
 return a/b;
}

будет вызван с параметрами (1, 0)?

Вы почему throws ZerroDivide нигде не пишете?


 
DiamondShark ©   (2006-03-21 18:17) [67]


> Игорь Шевченко ©   (21.03.06 18:10) [65]

Телепатия :)


 
DiamondShark ©   (2006-03-21 18:22) [68]


> вот эти копирования сигнатур шибко напрягают, признаюсь

рано или поздно все выучат заклинание "throws Thowable" и забудут про Фундамент(тм) как про страшный сон
:)


 
Lamer@fools.ua ©   (2006-03-21 18:23) [69]

>>DiamondShark ©   (21.03.06 18:16) [66]

А операция деления throws ZeroDivideException или как-там его, насколько я понимаю. Посему, либо обрабатываем сами, либо указываем в заголовке, чтоб оставляем на откуп вызвавшему.


 
Lamer@fools.ua ©   (2006-03-21 18:27) [70]

чтоб оставляем -> что оставляем


 
Игорь Шевченко ©   (2006-03-21 18:28) [71]

Lamer@fools.ua ©   (21.03.06 18:23) [69]


> Посему, либо обрабатываем сами


А эта...зачем тогда наружу вообще что-либо выбрасывать, можно самому обрабатывать. Ну и наружу код возврата, как в старые добрые времена.


> либо указываем в заголовке, чтоб оставляем на откуп вызвавшему


То есть, каждый метод, кроме a + b должен в заголовке писать Throws EAccessViolation или как там он в Java называется ? :)


 
DiamondShark ©   (2006-03-21 18:41) [72]


> Lamer@fools.ua ©   (21.03.06 18:23) [69]

Для всех операций есть список декларированных исключений?

Я почему спрашиваю. Интересно, что будет, если произойдёт недекларированное исключение.
Конечно, если ВСЕ операции считаются методами с декларированными исключениями, то такой ситуации теоретически быть не может.

Но интересно же... :)


 
pasha_golub ©   (2006-03-21 18:48) [73]


> То есть, каждый метод, кроме a + b должен в заголовке писать
> Throws EAccessViolation или как там он в Java называется
> ? :)


Гыгы. Блин. По хорошему можно сразу весь список доступных эксепшнов.


 
Lamer@fools.ua ©   (2006-03-21 18:57) [74]

>>Игорь Шевченко ©   (21.03.06 18:28) [71]

>То есть, каждый метод, кроме a + b должен в заголовке писать Throws EAccessViolation или как там он в Java называется ? :)
Я совсем не спец по Java, но поскольку он весьма похож на .NET, рискну предположить, что как и в .NET, пользовательский код не может бросить исключения типа AccessViolationException. Правда, в .net (точнее в c#) есть unsafe код. В нём такое исключение может произойти.

>>DiamondShark ©   (21.03.06 18:41) [72]

Опять же, я совсем не спец по Java, но поскольку он весьма похож на .NET, подозреваю, что как и в .NET все операции — это просто перегруженные операторы у классов и структур. Соотвественно для них действуют те же правила о "throws".

З.Ы.
Что меня самого интересует, так это исключение NullReferenceException (так в .NET называется, как в Java — не знаю). От него особо не застрахуешься, когда есть конструкции вида:
a.b[i].c
А вдруг a, b или b[i] равны null?


 
pasha_golub ©   (2006-03-21 20:59) [75]


> Что меня самого интересует, так это исключение NullReferenceException
> (так в .NET называется, как в Java — не знаю). От него особо
> не застрахуешься, когда есть конструкции вида:
> a.b[i].c
> А вдруг a, b или b[i] равны null?

Во, во... Именно это и имелось ввиду.


 
Игорь Шевченко ©   (2006-03-21 21:05) [76]

Lamer@fools.ua ©   (21.03.06 18:57) [74]


> Я совсем не спец по Java, но поскольку он весьма похож на
> .NET, рискну предположить, что как и в .NET, пользовательский
> код не может бросить исключения типа AccessViolationException.
>  Правда, в .net (точнее в c#) есть unsafe код. В нём такое
> исключение может произойти.


В .Net код очень даже может выбросить Exception, которого совсем не ждешь. Причем, хотя ноги у него растут от NullReference, наверное из-за таких вот throws-конструкций окончательный Exception получается совсем другой (но, опять же, неожиданный). В опытах с D2005 такие примеры довольно легко получаются, достаточно требуемую сборку расположить вне поля видимости :)


 
Petr V. Abramov ©   (2006-03-21 21:10) [77]

> Игорь Шевченко ©   (21.03.06 21:05) [76]
> В .Net код очень даже может выбросить Exception, которого совсем не ждешь.
 Я так понял, что если какая-то неожиданная (даже самим автором метода) фигня вылезет, но она не указана в throws, то все пойдет, как в старом добром Delphi32


 
Petr V. Abramov ©   (2006-03-21 21:22) [78]

> [77]
 Точнее, конечно, сказать, предположил из соображений здравого смысла :)))


 
iZEN ©   (2006-03-21 21:25) [79]

>Игорь Шевченко ©   (21.03.06 18:10) [65]
> Я извиняюсь за оверквотинг, но если из-за кривости рук программиста, написавшего Login(...) из него выскочит какой-то другой Exception из неуказанных в сигнатуре метода, то что произойдет и как мне поможет компилятор ?

>DiamondShark ©   (21.03.06 18:16) [66]
>Кстати, а что произойдёт, если метод всё-таки выбросит недекларированное исключение?
>ну вот например метод, вроде такого
>int MyCrazzyMethod(int a, int b)
>{
> return a/b;
>}
>будет вызван с параметрами (1, 0)?
>Вы почему throws ZerroDivide нигде не пишете?

Если вам так важно объявить о том, что код метода потенциально может произвести деление на ноль и бросить исключение, то можете совершенно спокойно объявить класс ZerroDivide наследником Exception (но только не наследником RuntimeException!), в теле метода перехватить runtime-исключение ArithmeticException, в блоке catch бросить важное вам исключение:

public class ZerroDivide extends Exception {}


public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b) throws ZerroDivide {
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
}

и люди, которые будут использовать ваш код без исходников и документации, будут счастливы, так как с помощью без всяких запусков и тестов, только с помощью сообщений компилятора знают, где разложены грабли и попытаются на них не наступить уже в своём коде!

Недекларируемые исключения, как правило, относятся к подклассу RuntimeException, такие исключения в большинстве динамических языков есть непроверяемые исключения (unchecked exceptions). То же самое — подклассы Access Violation (хотя это я бы уже отнёс к Error, серьёзной ошибке времени выполнения), Null Pointer Exception, Null Reference Exception и другие.

Например, в иерархии наследования классов Java чётко прослеживаются три линии исключительных ситуаций:
* критические ошибки (errors), которые нельзя поймать в прикладном коде, они также непроверяемые (например, ошибка исчерпания свободной памяти: Throwable - Error - OutOfMemoryError) — на этапе выполнения аварийный останов системы исполнения;
* проверяемые исключения (Throwable - Exception - все потомки кроме RuntimeException) — компилятор отслеживает семантику использования уже на стадии компиляции;
* непроверяемые исключения (Throwable - Exception - RuntimeException - все потомки), которые можно поймать на этапе выполнения, но необязательно объявлять об их бросании, так как компилятор совсем не проверяет их семантику использования, — всё узнаётся только на этапе выполнения.
Здесь: Throwable — предок всех классов исключительных ситуаций и ошибок выполнения.

По-моему, программисты с ума бы сошли, если бы все исключения были бы проверяемыми. Представьте: в каждом методе писать список throws и/или вручную следить за целостностью ссылок (!= null), за ошибками выхода за границы массива, за ошибки приведения к типу (dynamic class casting), за переполнением при делении на ноль и т.д. Физически нецелесообразно объявлять все исключения проверяемыми. Да это и не нужно, если не надо расставлять акценты для защиты кода.


 
iZEN ©   (2006-03-21 21:32) [80]

Все классы-наследники java.lang.RuntimeException, таким образом, являются полными аналогами Exception в Delphi и C#.


 
iZEN ©   (2006-03-21 21:34) [81]

>Petr V. Abramov ©   (21.03.06 21:10) [77]
>> Игорь Шевченко ©   (21.03.06 21:05) [76]
>> В .Net код очень даже может выбросить Exception, которого совсем не ждешь.
>Я так понял, что если какая-то неожиданная (даже самим автором метода) фигня вылезет, но она не указана в throws, то все пойдет, как в старом добром Delphi32

Совершенно верно.
С системными ошибками времени выполнения похожая ситация.


 
wicked ©   (2006-03-21 21:36) [82]


> По-моему, программисты с ума бы сошли, если бы все исключения
> были бы проверяемыми. Представьте: в каждом методе писать
> список throws и/или вручную следить за целостностью ссылок
> (!= null), за ошибками выхода за границы массива, за ошибки
> приведения к типу (dynamic class casting), за переполнением
> при делении на ноль и т.д. Физически нецелесообразно объявлять
> все исключения проверяемыми. Да это и не нужно, если не
> надо расставлять акценты для защиты кода.

почти так сделано в Oberon - там исключений нету как класса, а то, что их заменяет, "ловушки", в коде просто так не перехватить....... это, конечно, AFAIK, поскольку близко с Обероном не работал.....


 
iZEN ©   (2006-03-21 21:37) [83]

Семантики использования throws <список_бросаемых_исключений> не существует ни в C#, ни в Delphi. Поэтому приходится использовать другие сигнальные механизмы. И только на стадии выполнения, к сожалению.


 
Игорь Шевченко ©   (2006-03-21 21:44) [84]

Petr V. Abramov ©   (21.03.06 21:10) [77]


>  Я так понял, что если какая-то неожиданная (даже самим
> автором метода) фигня вылезет, но она не указана в throws,
>  то все пойдет, как в старом добром Delphi32


Я с Java не знаком, поэтому не могу сказать. В .Net все пойдет также, как в старом добром Delphi - вылезет окошко, что программа совершила ужасное преступление и волей всех народов будет изнана с просторов оперативной памяти и на пять лет поражена в правах находиться в списке процессов.

iZEN ©   (21.03.06 21:25) [79]


> Физически нецелесообразно объявлять все исключения проверяемыми.


А нафига тогда проверяемые объявлять ? Все-таки, я присоединяюсь к просьбе Димы Акуличева и прошу привести пример, когда без проверямых исключений ни в какую не обойтись. Или ткнуть меня носом в номер поста, где такой пример уже приведен.


 
iZEN ©   (2006-03-21 22:20) [85]

>pasha_golub ©   (21.03.06 18:48) [73]
>> То есть, каждый метод, кроме a + b должен в заголовке писать
>> Throws EAccessViolation или как там он в Java называется ? :)
>Гыгы. Блин. По хорошему можно сразу весь список доступных эксепшнов.

>Lamer@fools.ua ©   (21.03.06 18:57) [74]
>>Игорь Шевченко ©   (21.03.06 18:28) [71]
>>То есть, каждый метод, кроме a + b должен в заголовке писать Throws EAccessViolation или как там он в Java называется ? :)
>Я совсем не спец по Java, но поскольку он весьма похож на .NET, рискну предположить, что как и в .NET, пользовательский код не может бросить исключения типа AccessViolationException. Правда, в .net (точнее в c#) есть unsafe код. В нём такое исключение может произойти.

Ладно, напишу что можно делать с исключениями в Java, но тогда пусть кто-то другой сделает аналогичные примеры на C#.
Итак, когда можно бросить и никогда не поймать ошибку системы времени выполнения:
public class ZerroDivide extends java.lang.Error {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b) throws ZerroDivide {
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       ArithmeticTest.MyCrazzyMethod(10, 0);
   }
}

Вывод в консоли:
ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:10)
Exception in thread "main"
Программа принудительно завершена с сообщением об ошибке.
Диалог системного сообщения: "Fatal exception occured. Program will exit." [OK]

Непроверяемые исключения:
public class ZerroDivide extends java.lang.RuntimeException {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b)  { /* писать в сигнатуре метода throws ZerroDivide необязательно - и так работает */
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       ArithmeticTest.MyCrazzyMethod(10, 0);
   }
}

Вывод в консоли:
ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:10)
Exception in thread "main"
Программа принудительно завершена с сообщением об ошибке.
Диалог системного сообщения: "Fatal exception occured. Program will exit." [OK]

Проверяемое исключение:
public class ZerroDivide extends java.lang.Exception {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b) throws ZerroDivide {
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       /* Компилятор потребовал наличия конструкции try/catch или декларации throws в сигнатуре метода main. Сделал try/catch. */
       try {
           ArithmeticTest.MyCrazzyMethod(10, 0);
       } catch (ZerroDivide e) {
           e.printStackTrace();
       }
   }
}

Вывод в консоли:

ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:12)
Объект исключения e вывел трассу вызовов методов в стэке, похожую на предыдущие случаи. И программа спокойно завершилась, так как ей выполнять больше нечего (в двух предыдущих случаях программа завершилась в досрочно-принудительном порядке).

Вот, в общем-то, иллюстративный материал.


 
Petr V. Abramov ©   (2006-03-21 22:35) [86]

> Игорь Шевченко ©   (21.03.06 21:44) [84]
> Я с Java не знаком, поэтому не могу сказать.
 Взаимно. Сужу по постам знакомых :))
> В .Net все пойдет также, как в старом добром Delphi
 С .нет также не знаком, верю на слово
> - вылезет окошко, что программа совершила ужасное преступление и
> волей всех народов будет изнана с просторов оперативной памяти и на
> пять лет поражена в правах находиться в списке процессов.
 где-то помнится видел... :))
 С кем не бывало...

 Ну и что? К раз-кому AV отношения не имеет.
Ну придумали идею < не буду повторять посты любиетелй жаба> Идея имеет право на жизнь. Ну не повторили ее в тчкНет. И что?


 
iZEN ©   (2006-03-21 22:38) [87]

Кстати, допустил небольшую неточность в высказывании "когда можно бросить и никогда не поймать ошибку системы времени выполнения". Бросить можно и поймать можно.

java.lang.Error относится к непрверяемым исключениям (Unchecked Exceptions). То есть семантика обработки почти такая же, как и у java.lang.RuntimeException и, по аналогии, как у Delphi и C#.

Но важный момент: потомки java.lang.Error могут возникнуть самопроизвольно в прикладном коде, если виртуальная машина испытывает серьёзные проблемы в работе. Перехватить их можно в блоке catch (Error e) {...} или catch (Throwable e) {...}, но, как правило, это уже не имеет большого смысла для корректного завершения работы.


 
Игорь Шевченко ©   (2006-03-21 22:46) [88]

iZEN ©   (21.03.06 22:38) [87]

И все-таки, народу непонятно, зачем нужны checked exceptions...


 
Lamer@fools.ua ©   (2006-03-21 22:52) [89]

>>Игорь Шевченко ©   (21.03.06 21:05) [76]

>В .Net код очень даже может выбросить Exception, которого совсем не ждешь.

Естественно. Out of memory, Stack overflow и др. никто не отменял. Я конкретно о AccessViolationException написал. Слово "типа", в общем-то, было лишнее.

P.S.
По большому счёту, NullReferenceException — это реакция на спровоцированный Access Violation. Я смотрел, как это реализовывается. После получения адреса объекта, скажем, в регистр ECX перед обращением к члену класса исполняется следующий код:
cmp         dword ptr [ecx], ecx
В случае managed safe code в ECX может содержаться только одно из двух: либо нуль либо указатель на существующий объект.
Если в ECX нуль, то очевидно, что при исполнении вышеприведенного кода возникнет исключительная ситуация, которая неким образом обработается и сгенерируется NullReferenceException.

P.P.S.
Реальный AccessViolationException я наблюдал всего однажды, когда NOD32 не подружился с фреймворком 2.0. После чего NOD32 пришлось снести.


 
Petr V. Abramov ©   (2006-03-21 22:52) [90]

А как б... женатому человеку - вроде не нужны, но если уж есть, то можно и  попользоваться  Ж)))


 
Игорь Шевченко ©   (2006-03-21 23:47) [91]

Lamer@fools.ua ©   (21.03.06 22:52) [89]


> Я конкретно о AccessViolationException написал


Как уже было сказано одним из предыдущих ораторов, внутри unsafe-кода оно вроде может возникнуть. У меня такой вопрос, если я вызываю неую сборку, о деталях устройства которой не знаю, а она, вдруг возьми и работай с unsafe-кодом, например, вызывая какие-то старенькие библиотеки, и если в момент вызова внутри кода возник AccessViolation, то передастся ли он наверх, при условии, что сборка сама его не обрабатывает ?


 
Lamer@fools.ua ©   (2006-03-22 09:00) [92]

>>Игорь Шевченко ©   (21.03.06 23:47) [91]

>Как уже было сказано одним из предыдущих ораторов, внутри unsafe-кода оно вроде может возникнуть.
По-моему мной же =)

У меня такой вопрос, если я вызываю неую сборку, о деталях устройства которой не знаю, а она, вдруг возьми и работай с unsafe-кодом, например, вызывая какие-то старенькие библиотеки, и если в момент вызова внутри кода возник AccessViolation, то передастся ли он наверх, при условии, что сборка сама его не обрабатывает ?
Меня так и подмывает ответить одной из Ваших любимых фраз: практика — критерий истины :-)
Но вообще ответ — да.

P.S.
Только одно замечание. Unsafe код — это не работа с не .Net библиотеками. Это специальный механизЬм в .Net (точнее даже в C#). Работа с COM/OLE и обычными (не .Net) библиотеками осуществляется посредством механизма, именуемого Interop (interoperability).


 
FastReporter   (2006-03-22 10:40) [93]

KSergey ©   (21.03.06 18:01) [64]

Теперь получается так: я должен оббежать все 10 методов - и выяснить: а какого же они могут выкинуть фердебобеля? Ага, до фига всего.

В современных IDE типа IntelliJIdea добавление исключения во throws происходит по одному нажатию кнопки или мыши. Но дело даже не в этом.

Игорь Шевченко ©   (21.03.06 18:10) [65]

Я извиняюсь за оверквотинг, но если из-за кривости рук программиста, написавшего Login(...) из него выскочит какой-то другой Exception из неуказанных в сигнатуре метода, то что произойдет и как мне поможет компилятор ?

Вы сейчас привели аргумент как раз в пользу CheckedException. В том то и дело, что указанная ситуация попросту невозможна. Будет ошибка компиляции, если кидается недекларированное исключение.


 
FastReporter   (2006-03-22 10:41) [94]

DiamondShark ©   (21.03.06 18:16) [66]

Вы почему throws ZerroDivide нигде не пишете?

Это Run-time (unchecked exception). Незачем писать к каждому методу TOutOfElectricityException :)


 
Игорь Шевченко ©   (2006-03-22 11:31) [95]

FastReporter   (22.03.06 10:40) [93]


> Вы сейчас привели аргумент как раз в пользу CheckedException.
>  В том то и дело, что указанная ситуация попросту невозможна.
>  Будет ошибка компиляции, если кидается недекларированное
> исключение.



> Это Run-time (unchecked exception). Незачем писать к каждому
> методу TOutOfElectricityException :)


Ну вот. А как же тогда недекларированность ? :)


 
Sandman25 ©   (2006-03-22 15:13) [96]

Игорь Шевченко ©   (22.03.06 11:31) [95]

Ох. Представьте себе сложные системы, когда самый последний в цепочке вызовов метод m1 генерирует исключение E1 и E2, вызывающий его m2 перехватывает E1 и сам генерирует E3 и E4, вызывающий его m3 перехватывает E4, добавляет E5,E6,E7 и т.д. Вопрос: насколько просто будет в Delphi отследить, все ли нужные ошибки обработаны и какие остались еще необработанными? А в java в этом поможет компилятор. Причем использовать указанные возможности необязательно (хотя, в принципе, желательно, не зря throws задейцствовано и в javadoc).
В общем, резюмирую. Каждый овощ хорош... (с) Вы :)


 
Игорь Шевченко ©   (2006-03-22 15:28) [97]

Sandman25 ©   (22.03.06 15:13) [96]


> Представьте себе сложные системы, когда самый последний
> в цепочке вызовов метод m1 генерирует исключение E1 и E2,
>  вызывающий его m2 перехватывает E1 и сам генерирует E3
> и E4, вызывающий его m3 перехватывает E4, добавляет E5,E6,
> E7 и т.д. Вопрос: насколько просто будет в Delphi отследить,
>  все ли нужные ошибки обработаны и какие остались еще необработанными?
>  


> Вопрос: насколько просто будет в Delphi отследить, все ли
> нужные ошибки обработаны и какие остались еще необработанными?
>  


Уважаемый Александр, как я уже не один раз говорил, Exception по моим понятиям является исключительной ситуацией, а не механизмом реализации программной логики. Я не спорю, есть и такие программы, поведение которых основывается на возбуждении exceptions и последующей их обработки, только по моему скромному опыту отлаживать такие программы крайне неудобно. Надеюсь, с тем, что программы приходится отлаживать, спорить здесь никто не будет.

Собственно, этот подход и рождает мое непонимание необходимости декларировать порождаемые исключения.

С наилучшими!


 
Sandman25 ©   (2006-03-22 15:33) [98]

Игорь Шевченко ©   (22.03.06 15:28) [97]

Ладно, всё понятно.

С наилучшими.


 
iZEN ©   (2006-03-22 16:17) [99]

Игорь Шевченко ©   (22.03.06 15:28) [97]
>Уважаемый Александр, как я уже не один раз говорил, Exception по моим понятиям является исключительной ситуацией, а не механизмом реализации программной логики.
>Я не спорю, есть и такие программы, поведение которых основывается на возбуждении exceptions и последующей их обработки, только по моему скромному опыту отлаживать такие программы крайне неудобно.
>Собственно, этот подход и рождает мое непонимание необходимости декларировать порождаемые исключения.

Что делать, если исключительные ситуации возникают в нескольких нитях? Как за этим следить, если есть только один контролирующий механизм, работающий на стадии выполнения приложения в виде непроверяемых на стадии компиляции Runtime Exception"s? Ошибки, рано или позно, в могопоточном приложении будут вылезать наружу, отдельные нити сами-собой будут прекращать существование по непонятным причинам с мерзким системным сообщением об ошибке. Естественно, программистами будут предприниматься меры по пересозданию убитых нитей (что является довольно-таки затратной операцией) в приложении. Хотя всё это можно было оформить в структурированную систему обработки ошибок с привлечением компилятора ещё на стадии проверки кода на корректность.

>Надеюсь, с тем, что программы приходится отлаживать, спорить здесь никто не будет.

Никто не спорит. Десят лет в Delphi все только так и делали.


 
Игорь Шевченко ©   (2006-03-22 16:34) [100]

iZEN ©   (22.03.06 16:17) [99]


> Ошибки, рано или позно, в могопоточном приложении будут
> вылезать наружу, отдельные нити сами-собой будут прекращать
> существование по непонятным причинам с мерзким системным
> сообщением об ошибке. Естественно, программистами будут
> предприниматься меры по пересозданию убитых нитей (что является
> довольно-таки затратной операцией) в приложении


Ошибки вылезают наружу не только в многопоточных приложениях, но даже и в однопоточных. Не совсем понимаю, зачем нужно пересоздавать убитые нити, а самое главное, чего я не понимаю, это каким образом объявление checked-exceptions может помочь решить эту проблему.


> Как за этим следить, если есть только один контролирующий
> механизм, работающий на стадии выполнения приложения в виде
> непроверяемых на стадии компиляции Runtime Exception"s?
>



> Хотя всё это можно было оформить в структурированную систему
> обработки ошибок с привлечением компилятора ещё на стадии
> проверки кода на корректность


Я извиняюсь, а стуктурированная система какие ошибки будет обрабатывать, которые в рантайм возникают или которые возникают по воле самой программы ?

И, попробую еще раз повторить свою просьбу о примере, наглядно показывающем все преимущества checked-exceptions.


> Десят лет в Delphi все только так и делали.


В java программы не отлаживают ? Просто интересно...


 
iZEN ©   (2006-03-22 17:27) [101]

Игорь Шевченко ©   (22.03.06 16:34) [100], ну что ещё я могу сказать? Слов почти не осталось.

>И, попробую еще раз повторить свою просьбу о примере, наглядно показывающем все преимущества checked-exceptions.

Ну не буду же приводить в качестве примера исходники JUnit и Jakarta Tomcat. Это будет интересно немногим да и места здесь займёт...Но в следующем коде я ходя бы попытаюсь продемонстрировать важность работы с проверяемыми исключениями (улучшенный мной код другого автора):

package ru.skipy.net.protocol.jarres;
/**
* URLConnection implementation for jarres protocol.
* @author Eugene Matyushkin
* @version 1.(1)
*/
import java.io.*;
import java.net.*;
public class JarResourceURLConnection extends URLConnection {
   private String resourcePath;
   private boolean connected = false;
   private InputStream is = null;
   public JarResourceURLConnection(URL url) {
       super(url);
       resourcePath = url.getPath();
   }
   public synchronized void connect() throws IOException {
       if (connected)
           return;
       is = new ByteArrayInputStream(readData());/* в случае исключения выход "вверх по стэку" */
       connected = true;
   }
   private byte[] readData() throws IOException {
       InputStream resourceStream = getClass().getResourceAsStream(resourcePath);
       if (resourceStream == null)
           throw new IOException("Ресурс недоступен.");
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       DataInputStream dis = new DataInputStream(resourceStream);
       byte[] buffer = new byte[16384];/* такое ограничение когда-нибудь аукнется */
       while (true) {
           int readed = dis.read(buffer);
           if (readed == -1)
               break;
           if (readed > 0)
               baos.write(buffer, 0, readed);
       }
       return baos.toByteArray();
   }
   public synchronized InputStream getInputStream() throws IOException {
       try {
           connect();
       } catch (IOException ioex) {
           /* Вот здесь и ловим IOException "Ресурс недоступен." и отправляем его дальше с дельной информацией */
           throw new FileNotFoundException(resourcePath + " - "
               + ioex.getMessage());
       }
       return is;/* отдаём ссылку, если всё в порядке */
   }
}


Проверяемые исключения дисциплинируют и направляют принятие решения о структурированной обработке исключений, а не о разбросанности по разным местам методов-ловцов всеможных ракообразных, встречающихся в тёмных "водах" Windows и в чужих плохо документированных библиотеках.

Эффективность таких исключений просто в их большей детальности, в прозрачности тех мест, где они могут возникнуть точно. Программисту остаётся лишь написать соответствующий "экран" на пути распространения известных исключений. И в этом ему помогает прежде всего компилятор, а не единственное средство в виде отладки.


 
Игорь Шевченко ©   (2006-03-23 10:10) [102]


> Проверяемые исключения дисциплинируют и направляют принятие
> решения о структурированной обработке исключений


Что в данной фразе подразумевается под "структурированностью" ?

Теперь по коду:

1) не разумнее было бы (в данном конкретном случае), чтобы метод connect выбрасывал исключение EConnectError или EResourceUnavailable, вместо того, чтобы засорять мозги программисту ( компилятору) необходимостью запоминать, что при вызове connect и возникновении IOException необходимо сделать вывод о недоступности ресурса.
2) внутри методов выделяется память. Почему не написано, что метод connect может возбудить EOutOfMomery ?
3) зачем я указываю, что метод connect выбрасывает IOException - внутри метода явного throw нет, а запоминать, какие вызываемые методы какие исключения могут выбросить - а какой в этом глубокий смысл ? Кроме того, я не вижу, чтобы метод connect обрабатывал другие типы исключений, оставляя необработанным только IOException, чем и как мне в этом случае может помочь компилятор ?


 
iZEN ©   (2006-03-23 10:55) [103]

>Игорь Шевченко ©   (23.03.06 10:10) [102]
>> Проверяемые исключения дисциплинируют и направляют принятие решения о структурированной обработке исключений
>Что в данной фразе подразумевается под "структурированностью" ?

"Структурированность" здесь подразумевает одиный путь генерации и ловли известных исключений, а не "try/catch(Throwable anyEx) в нужных местах" (не нужно будет бить голову тому, кто это напишет).

>Теперь по коду:

>1) не разумнее было бы (в данном конкретном случае), чтобы метод connect выбрасывал исключение EConnectError или EResourceUnavailable, вместо того, чтобы засорять мозги программисту ( компилятору) необходимостью запоминать, что при вызове connect и возникновении IOException необходимо сделать вывод о недоступности ресурса.

Зачем плодить лишние сущности? Достаточно исключения ввода-вывода. Заметь, внутри класса генерируется только одно унифицированное исключение — IOException, конкретный экземпляр FileNotFoundException является его потомком, поэтому при желании пользователь этого класса может привести исключение к этому типу и получить, таким образом, конкретное описание ошибки. Но в большинстве случаев такой детальной информации не требуется, достаточно общего вида ошибки, что и отражено в сигнатурах методов.

>2) внутри методов выделяется память. Почему не написано, что метод connect может возбудить EOutOfMomery ?

Исключение OutOfMemoryError в Java (и в C#, и в Delphi) является непроверяемым исключением (и к тому же системной ошибкой в Java, приводящей к краху JVM, что в данном случае несущественно). Объявление непроверяемых исключений в списке throws ни к чему не обязывает компилятор. Компилятор следит за правильным использованием только проверяемых исключений. То есть OutOfMemoryError потенциально может произойти абсолютно в любом методе, throws для него не нужен.

>3) зачем я указываю, что метод connect выбрасывает IOException - внутри метода явного throw нет, а запоминать, какие вызываемые методы какие исключения могут выбросить - а какой в этом глубокий смысл ?

Метод cjnnect() не перехватывает (нет блока try/catch) исключений, которые могут произойти в методе readData(), а передаёт их вверх по стэку вызова. Просто мне удобнее здесь дать пользователю возможность использовать дуальность API этого класса: в одном случае использовать state-machine-model с пошаговым протоколом установления соединения и получения данных (connect(), getInputStream()), в другом случае использовать функциональный подход с вызовом метода как функции (просто getInputStream()). В обоих случаях семантика вызовов разная (можно использовать по-разному), но класс работает одинаково (меньше ошибок кода).

>Кроме того, я не вижу, чтобы метод connect обрабатывал другие типы исключений, оставляя необработанным только IOException, чем и как мне в этом случае может помочь компилятор ?

Зачем ещё что-то обрабатывать? Компилятор обращает внимание только на правильное использование IOException (делай try/catch в теле или throws в сигнатуре, иначе не буду компилировать), больше он ни о чём мне не говорит. Это же он скажет пользователю, который будет использовать данный библиотечный класс при любой семантике вызова.


 
Игорь Шевченко ©   (2006-03-23 11:11) [104]

iZEN ©   (23.03.06 10:55) [103]


> Просто мне удобнее здесь дать пользователю возможность использовать
> дуальность API этого класса: в одном случае использовать
> state-machine-model с пошаговым протоколом установления
> соединения и получения данных (connect(), getInputStream()),
>  в другом случае использовать функциональный подход с вызовом
> метода как функции (просто getInputStream()). В обоих случаях
> семантика вызовов разная (можно использовать по-разному),
>  но класс работает одинаково (меньше ошибок кода).


Переведи на понятный язык.


> Зачем плодить лишние сущности? Достаточно исключения ввода-
> вывода.


А оно как-то семантически связано с методом connect ? Для меня, например, первый раз увидевшего этот код (это вообще-то важный момент), никакой связи между connect и ошибкой ввода-вывода не усматривается.


> Зачем ещё что-то обрабатывать? Компилятор обращает внимание
> только на правильное использование IOException (делай try/catch
> в теле или throws в сигнатуре, иначе не буду компилировать),
>  


Я правильно понял, что если некий метод обращается к неким методам, в сигнатуре которых написано, что они throws некие exceptions, то этот метод либо обязан выполнять try/catch именно этих exceptions либо переносить их в свою сигнатуру ?


 
iZEN ©   (2006-03-23 11:57) [105]

>Игорь Шевченко ©   (23.03.06 11:11) [104]
>Переведи на понятный язык.

Есть разные решения одной и той же задачи. В одном случае пользователю требуется машина состояний (у него могут быть свои причины: типа плагин-оболочку делает к какой-то системе), в другом случае нужно просто получить байтовый поток.

>> Зачем плодить лишние сущности? Достаточно исключения ввода-вывода.
>А оно как-то семантически связано с методом connect ? Для меня, например, первый раз увидевшего этот код (это вообще-то важный момент), никакой связи между connect и ошибкой ввода-вывода не усматривается.

Семантика соединения в Java связана с вводом-выводом.

> Зачем ещё что-то обрабатывать? Компилятор обращает внимание
> только на правильное использование IOException (делай try/catch
> в теле или throws в сигнатуре, иначе не буду компилировать),
>>Я правильно понял, что если некий метод обращается к неким методам, в сигнатуре которых написано, что они throws некие exceptions, то этот метод либо обязан выполнять try/catch именно этих exceptions либо переносить их в свою сигнатуру ?

Да. И за этим жёстко следит компилятор. Компилятор не будет компилировать, если ни одно из этих условий не соблюдено. В этом вся соль Checked Exception"s.


 
Игорь Шевченко ©   (2006-03-23 12:11) [106]

iZEN ©   (23.03.06 11:57) [105]


> Есть разные решения одной и той же задачи. В одном случае
> пользователю требуется машина состояний (у него могут быть
> свои причины: типа плагин-оболочку делает к какой-то системе),
>  в другом случае нужно просто получить байтовый поток.


Да, сообразил.


> Да. И за этим жёстко следит компилятор. Компилятор не будет
> компилировать, если ни одно из этих условий не соблюдено.
>  В этом вся соль Checked Exception"s.


Мне все-таки кажется, что это лишняя нагрузка на программиста, которому надо следить за всем возбуждаемыми исключениями в вызываемых методах.

Кроме того, в одном из предыдущих постов, ты говорил, "зачем плодить лишние сущности" имея в виду ненужность создания EConnectError и утверждая, что IOException достаточно.
В таком случае, зачем введена лишняя сущность FileNotFoundException в методе getInputStream ? И почему не указано, что метод getInputStream throws FileNotFoundException ?


 
wicked ©   (2006-03-23 12:28) [107]

позволю себе вставить свои 5 коп...
> Игорь Шевченко ©   (23.03.06 12:11) [106]
> > Да. И за этим жёстко следит компилятор. Компилятор не
> будет
> > компилировать, если ни одно из этих условий не соблюдено.
>
> >  В этом вся соль Checked Exception"s.
>
>
> Мне все-таки кажется, что это лишняя нагрузка на программиста,
>  которому надо следить за всем возбуждаемыми исключениями
> в вызываемых методах.

когда-то пришлось делать один маленький проект на java и тогда я столкнулся с checked exceptions.... сначала было неприятно, что валидный, в общем то, код не компилируется... потом таки я понял, что таким образом разработчики насаждают аккуратность обработки ошибок, что не есть плохо.....
имхо, для того, чтобы оценить перелесть/ужас checked exceptions, нужно просто с ними поработать....
в любом случае, они есть в java и с этим уже ничего не поделаешь..... ;)


 
Суслик ©   (2006-03-23 12:33) [108]

Позвольте встряну.

Я неплохо знаю java. Могу сказать так, что мне в дельфи при реализации библиотек РАЗНЫМИ членами коллектива очень не хватает формального контракта между мной (пользователем библиотеки) и ей (библиотекой) в области разделения ответственности за обработку исключений (НЕ ошибок!!!). Мы сейчас делаем так, что в местах смычек кода, который разработан разными людьми, документируем семантику методов с использованием секции, аналогичной throws. Т.е. описываем те исключения, которые возбуждает метод из биболиотеки и которые несут семантическую нагрузку, на которую ОБЯЗАН реагировать пользователь библиотеки. Лично мне очень не хватает поддержики компилятором контроля за выполнением программастом-клиентом своих обязанностей по обработке исключений.


 
Игорь Шевченко ©   (2006-03-23 12:53) [109]

Суслик ©   (23.03.06 12:33) [108]


> Могу сказать так, что мне в дельфи при реализации библиотек
> РАЗНЫМИ членами коллектива очень не хватает формального
> контракта между мной (пользователем библиотеки) и ей (библиотекой)
> в области разделения ответственности за обработку исключений
> (НЕ ошибок!!!).


То есть, у вас в библиотеке логика построена на обработке исключений ? Или я не так понял ?


 
iZEN ©   (2006-03-23 13:20) [110]

>Игорь Шевченко ©   (23.03.06 12:11) [106]
>Мне все-таки кажется, что это лишняя нагрузка на программиста, которому надо следить за всем возбуждаемыми исключениями в вызываемых методах.

Кому-то, действительно, "лишняя".

>Кроме того, в одном из предыдущих постов, ты говорил, "зачем плодить лишние сущности" имея в виду ненужность создания EConnectError и утверждая, что IOException достаточно.
>В таком случае, зачем введена лишняя сущность FileNotFoundException в методе getInputStream ? И почему не указано, что метод getInputStream throws FileNotFoundException ?

Порой детали не так важны, но в случае надобности их можно получить:
FileNotFoundException fnex = (FileNotFoundException)ioex;
Я предпочёл более общий вариант исключения более детальному.

Кстати, есть пример подобного рода.
На собеседовании спрашивают, почему лучше иметь объект более абстрактного типа, чем конкретного, почему следующее выражение:
Map map = new HashMap();
более предпочтительнее, чем это:
HashMap map = new HashMap();
если вид контейнера определён только для API Map?

Всегда лучше исксусственно ограничить себя в возможностях, чем использовать лишь часть из общедоступных. В данном случае класс HashMap реализует интерфейс Map, но в программе нигде не используются дополнительные возможности HashMap, это просто контейнер с публичным интерфейсом. Хотя в любой момент можно расширить доступ к объекту путём приведения его к тому типу, кем он на самом деле является:
HashMap map2 = (HashMap)map;
где map2 — это ссылка на тот же самый объект, на который ссылается map.
После этого можно использовать расширенные свойства объекта, но только по ссылке map2.

Использование более общего IOException вместо конкретизированного потомка FileNotFoundException в примере выше — из той же оперы.


 
Игорь Шевченко ©   (2006-03-23 14:11) [111]

iZEN ©   (23.03.06 13:20) [110]


> Использование более общего IOException вместо конкретизированного
> потомка FileNotFoundException в примере выше — из той же
> оперы.


А использование более общего предка Throwable ? ;)


 
Суслик ©   (2006-03-23 14:12) [112]


>  [109] Игорь Шевченко ©   (23.03.06 12:53)
> То есть, у вас в библиотеке логика построена на обработке
> исключений ? Или я не так понял ?


(пожалуйста, прочти до конца:))

Нет. Не логика библиотеки построена на исключениях, а логика обработки непозитивной реакции библиотеки.

Вот пример. Ты знаешь, что я занимаюсь мат. моделями в экономике и образовательными программами на их основе. У нас сейчас программу пишут 2 человека. Объектная модель мат. модели совершенно обособлена. У нее есть 5-6 методов, с помощью которых на модель может воздействовать второй программист.

При этом есть одна генеральная правильная линия общения - все работает ОК. Т.е. второй программист добивается от моей модели того поведения, которое указано в имени метода. Но при этом есть исключительные случаи, когда задача, полученная моей моделью не может быть выполнена.

Что мне делать, чтобы сообщить второму программисту, об ошибке?
1. Возвращать код результата - число. Этот вариант совсем плох, т.к. если он забудет обработать ошибочный ответ, то никто не узнает о том, что была ошибка.
2. Возбудить исключение. Это лучше. Но этого недостаточно, т.к. исключения несу, скорее, смысловую нагрузку, чем информацию об ошибках. Поэтому просто бросить исключение и думать, что на него кто-то среагирует мне не всегда достаточно. Я хочу заставить второго программиста среагировать на исключение, потому как это не ошибка, а часть поведения программы.

Надеюсь, понятно.


 
Игорь Шевченко ©   (2006-03-23 14:13) [113]

Суслик ©   (23.03.06 14:12) [112]


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


Чем это отличается от


> у вас в библиотеке логика построена на обработке исключений


?


 
Суслик ©   (2006-03-23 14:14) [114]

добавлю, ясное дело, что от дурака защититься сложно - второй программист может поставить просто заглушку. Но тогда он будет не второй программист, а 132 где нить в другом месте, а не у меня :)


 
Суслик ©   (2006-03-23 14:15) [115]


>  [113] Игорь Шевченко ©   (23.03.06 14:13)

Я не понял, ты хочешь на [113] получить ответ или услышать пример использования checked exceptions? :)


 
Игорь Шевченко ©   (2006-03-23 14:17) [116]

Суслик ©   (23.03.06 14:15) [115]

Пример использования мне написали в [101].

Я же хочу сказать, что отлаживать программу, частью логики которой является возбуждение исключений и их обработка, крайне неудобно.

"Плавали, знаем" (с) мореплавание Солнышкина.


 
Суслик ©   (2006-03-23 14:18) [117]


> Я же хочу сказать, что отлаживать программу, частью логики
> которой является возбуждение исключений и их обработка,
> крайне неудобно.

У тебя есть альтернативы для примера из [112]?
В студию, пожалуйста.


 
Игорь Шевченко ©   (2006-03-23 14:20) [118]


> 1. Возвращать код результата - число. Этот вариант совсем
> плох, т.к. если он забудет обработать ошибочный ответ, то
> никто не узнает о том, что была ошибка.
> 2. Возбудить исключение. Это лучше. Но этого недостаточно,
>  т.к. исключения несу, скорее, смысловую нагрузку, чем информацию
> об ошибках. Поэтому просто бросить исключение и думать,
> что на него кто-то среагирует мне не всегда достаточно.
> Я хочу заставить второго программиста среагировать на исключение,
>  потому как это не ошибка, а часть поведения программы.


Я бы код возвратил.


 
Думкин ©   (2006-03-23 14:21) [119]

А если он забудет обработать код - то будет работать 133-м где-то тоже далеко.


 
pasha_golub ©   (2006-03-23 15:14) [120]

Дык, а почему нельзя сделать унифицированный обработчик возвращаемого кода?

типо

procedure Check(ErrCode: integer);
begin
case ErrCode of
 ERR_FILE_NOT_FOUND: raise EFileNotFound.Create("blablabla");
 ERR_...
end;
end;

Соответственно вызов метода будет

Check(GetSizeOfSomeFile("path"));

Пример взят из той же самой Делфи, модуль DbTables.pas, где процедура Check выглядит как:


procedure Check(Status: DBIResult);
begin
 if Status <> 0 then DbiError(Status);
end;


 
iZEN ©   (2006-03-23 15:16) [121]

>Игорь Шевченко ©   (23.03.06 14:11) [111]
>А использование более общего предка Throwable ? ;)
Тогда будет потеря информации об исключении. Это как в анегдоте:
- Петька, приборы!!!!
- 29!
- Что 29?!
- А что приборы?
(, где "Приборы" & "29" == Throwable).


 
DiamondShark ©   (2006-03-23 15:21) [122]


> Я бы код возвратил.

Тогда макароны из if-ов получатся. От их написания и, тем более, чтения становится тоскливо.


 
DiamondShark ©   (2006-03-23 15:31) [123]

А, чуть не забыл.

This material should be approached with an open mind, studied carefully, and criticaly considered.

;-)


 
Игорь Шевченко ©   (2006-03-23 15:35) [124]

DiamondShark ©   (23.03.06 15:21) [122]

А так получаются макароны из try/catch - какая разница, только писать дольше.


 
DiamondShark ©   (2006-03-23 16:20) [125]


> Игорь Шевченко ©   (23.03.06 15:35) [124]

В том-то и дело, что не получаются.

Эх... нет под рукой текста недавнего моего сокетно-файлово-одбсёвого проекта...


 
Суслик ©   (2006-03-23 16:31) [126]

кто-то тут писал, что нужно попробовать, тогда станет ясно, зачем это нужно. Причем нужно попробовать не в роли юзера библиотеки, а в роли разработчика, которому не все равно, как она (библиотека) будет использоваться, т.к. он (разработчик библиотеки) скорее всего отвечает больше, чем за разработку той самой библиотки (например, руководит).


 
Игорь Шевченко ©   (2006-03-23 16:33) [127]

DiamondShark ©   (23.03.06 16:20) [125]

А разве анализ разных exceptions не равноценен анализу разных кодов возврата ?

Или вы имеете в виду, что получается код вида

if Foo = SUCCESS then
 if Bar = SUCCESS then
   if FooBar = SUCCESS then
     DoRealWork
   else
     Die
 else
   Die
else
 Die

вместо

 try
   Foo;
   Bar;
   FooBar;
   DoRealWork;
 except
   Die;
 end;

?


 
Игорь Шевченко ©   (2006-03-23 16:34) [128]

Суслик ©   (23.03.06 16:31) [126]


> кто-то тут писал, что нужно попробовать, тогда станет ясно,
>  зачем это нужно


А я, собственно, пробовал...Не на java правда. Я свои суждения из опыта выношу, так ска-ать.


 
DiamondShark ©   (2006-03-23 16:43) [129]


> Игорь Шевченко ©   (23.03.06 16:33) [127]

Примерно, что-то в этом роде, да.


 
Суслик ©   (2006-03-23 16:45) [130]


>  [128] Игорь Шевченко ©   (23.03.06 16:34)

а ты на ней, на java, попробуй.
Ты знаешь, действительно дисциплинирует.
Вот скажи, нет у тебя мечты, чтобы у тебя были дисциплинированные программисты? Наверное, есть. Ясный перец, что только checked expetion"ами их не дисциплинируешь. Но это тоже что-то. Конечно, можно сказать, что рубль дисциплинирует. Но ... тут спорить не буду. :)

Потом, не забывай, что java фреймвоковый язык, для которого разработана туча сред обитания. Одних серверов приложений сколько. В java также есть рефлексия. Как разработчику сервера тебе не плохо бы знать, какие исключения выбрасывает метод. Ясное дело, что runtime exception никто не запрещал возбуждать. А вот другие, явно возбуждаемые в методе ДОЛЖНЫ быть описаны в секции throws (иначе не скомпилиться). Т.е. по сути обсуждаемый механизм есть подписание контракта между тобой (разработчиком логики) и сервером приложений. Вот.


 
Игорь Шевченко ©   (2006-03-23 17:03) [131]

Суслик ©   (23.03.06 16:45) [130]

Эх, молодость, молодость....

DiamondShark ©   (23.03.06 16:43) [129]

Это безусловно верно, код получается менее макаронным. В случае использования exception, как сигнализации об ошибке, после которой должна следовать естественная смерть (в рамках какого-то участка кода), я и сам так рекомендую делать. В случае же, когда тип исключения начинает определять логику программы (и таких примеров можно найти), например, как в [120], программу становится крайне неудобно отлаживать. Потому что при попытке выполнить в отладчике шаг на следующую строку, меня выбрасывает в то место, где произошло исключение.


 
Суслик ©   (2006-03-23 17:21) [132]


>  [131] Игорь Шевченко ©   (23.03.06 17:03)

Крайне не понятны Ваши слова про молодость. Неконсруктивно это.

В [130] упомянуты сервера приложений, коих масса. Есть ощущение, что их тоже молодые делают? :)


 
Игорь Шевченко ©   (2006-03-23 17:28) [133]

Суслик ©   (23.03.06 17:21) [132]

Да я завидую... ;)


 
Verg ©   (2006-03-23 17:37) [134]

Игорь Шевченко ©   (23.03.06 16:33) [127]

if foo <> SUCCESS then die("foo") else
if bar <> SUCCESS then die("bar") else
.............
и т.д.

Будет по крайней мере понятно из-за кого случился die и для этого восе не обязательно, чтобы foo, bar и т.д. генерировали специфические типы exceptions или разные коды ошибок


 
Суслик ©   (2006-03-23 21:32) [135]


> Игорь Шевченко ©   (23.03.06 17:28) [133]
> Да я завидую... ;)

да я понимаю :)))))))))))))


 
GrayFace ©   (2006-03-24 11:16) [136]

> iZEN ©   (21.03.06 12:20) [44]
> >GrayFace ©   (21.03.06 11:12) [43]
> >Сколько ни программировал - ни разу "половины случаев"
> не встречал. >По-моему, самое частое исключение - это Access
> Violation.
> Ну и что, по-вашему, послужило причиной Access Violation?
>  Скорее всего не знаете. А это рантайм-исключение (Unchecked),
>  вызванное обращением к неразмеченной области памяти (скорее
> всего Null Pointer Exception). Но оно слишком общее, чтобы
> судить о контексте выполнения в работающей системе. Кстати,
>  под него очень часто подпадают необработанные исключения,
>  которые возникают в библиотечных методах — в тех самых
> "малозаметных узких местах". Вы их не видите, потому что
> не обрабатываете там, где следовало бы просто из-за недостатка
> информации о реальной сигнатуре метода (когда вызываемый
> метод бросает явное или неявное исключение). Исполняющая
> система Delphi ловит "наверху" всё, по определению, вот
> и выдаёт слишком общее сообщение об ошибке.

Поверьте, я знаю, что говорю.
Если учесть, что все библиотеки Windows не бросают исключений (в 99% случаев), не надо быть семи пядей во лбу, чтобы понять, что никаких "малозаметных узких мест" нету и причина в залазенье за границы масиива и т.п.
Я это к тому, что говорить о "узких местах" в половине случаев абсурдно, т.к. в половине случаев сторонние библиотеки вообще не используются.
А единственное, что не выдается "наверху" про AV - это класс исключения, если это наследник. Только наследники AV - это рекость, да и никто не мешает в Application.OnException вызывать обычный ShowException.

Что я не понимаю в идее checked exceptions - это необходимость явно прописывать бросаемые исключения. Почему бы просто не добавить некоторый хинт по возможным исключениям метода, который будет генериться оболочкой при наведении курсора?



Страницы: 1 2 3 4 вся ветка

Форум: "Прочее";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.97 MB
Время: 0.047 c
15-1142533379
lookin
2006-03-16 21:22
2006.04.16
И еще про спорт... Сенсационные результаты плей-офф по хоккею...


4-1138371915
mm0
2006-01-27 17:25
2006.04.16
Как грамотно запретить запуск второй копии программы?


6-1136373049
ingine
2006-01-04 14:10
2006.04.16
TIdFtp


15-1143223111
Kerk
2006-03-24 20:58
2006.04.16
Моменты в жизни, о которых вы никогда не забудете...


15-1143256110
balepa
2006-03-25 06:08
2006.04.16
Отправьте мне WIN32.hlp





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский