Смогу :-) Тоже, что любой вменяемый сделает в случае отказа электроснабжения - восстановлю битый конфиг из копии при следующем запуске и начну сессию с последнего чек-поинта :-) Такие дела :-)
Но это всё не является поводом не стремиться к лучшему, правда?
Правда. Вот только у меня есть опасения, что ради гарантий придётся пожертвовать удобством. И вижу подтверждения этого в том, что языки, пытающиеся выйти из ниши «исследовательских», дают всякие лазейки для обхода гарантий.
Например, Go. Несмотря на все разговоры про «errors are values», всё равно присутствуют defer/panic/recover. Хотя даже в FAQ есть пункт про то, что в языке «нет исключений».
Или Rust - паника, опять же, присутствует. При этом обрабатывать её ещё менее удобно, чем в Go. Вероятно, это «подталкивает» разработчиков использовать явные возвраты ошибок через Option/Result, но мы ведь говорим о гарантиях.
В уже упомянутой скале есть и Either/Option и исключения.
В Swift ещё забавнее. В обжектив-С ведь исключений толком не было, так что свифт продолжает использовать возврат ошибок. Вот только там применяется сахар и реальных типов возможных исключений просто не видно. В сигнатуре функции будет только «throws».
Или Rust - паника, опять же, присутствует. При этом обрабатывать её ещё менее удобно, чем в Go. Вероятно, это «подталкивает» разработчиков использовать явные возвраты ошибок через Option/Result, но мы ведь говорим о гарантиях.
panic в Rust и error в Haskell предназначены сигнализации об ошибках в коде, и обрабатывать их не следует вообще.
When the function F calls panic, execution of F stops, any deferred functions in F are executed normally, and then F returns to its caller. To the caller, F then behaves like a call to panic
Имхо, достаточно даже факта того, что в самой Java есть RuntimeException, если не ошибаюсь, которое может выскочить несмотря на все checked exceptions. И, следовательно, код на Java нужно писать оглядываясь на то, что из некого метода f() может выскочить не только те исключения, которое перечислены у него в throws.
Все верно, но ведь вам никто не мешает перехватить и RuntimeException, если уж так хочется, только вот это будет дурным тоном.
Да тот же OutOfMemoryError при нехватке памяти можно поймать, и, если сильно приспичит, изменить алгоритм работы для восстановления (урезание выделения памяти, допустим).
Но, повторюсь, лично для меня перехватывать RuntimeException и иже с ними - признак дурного тона, ибо это показатель некомпетентности разработчика, пытающегося «заглушить» последствия, вместо того, чтобы найти и устранить причину непосредственно в самом коде, т.к. ошибка выполнения по определению - показатель кривого кода в 99% случаев (1%, так и быть, отдам экстраординарным ситуациям).
Все верно, но ведь вам никто не мешает перехватить и RuntimeException, если уж так хочется
Речь не о том, что нельзя перехватывать RuntimeException. А о том, что список задекларированных в throws исключений отнюдь не исчерпывает список тех исключений, которые могут выскочить. Т.е. если где-то кто-то написал что-то вроде:
class Service {
public void doSomething() throws FileNotFoundException {...}
...
}
class Client {
public void useService(Service svc) {
try {
SomeResource res = allocateSomeResource();
svc.doSomething();
res.close();
}
catch(FileNotFoundException ex) {
handleProblem(ex);
res.close();
}
}
...
}
То он заложил в свой код потенциальную утечку ресурсов.
ошибка выполнения по определению - показатель кривого кода в 99% случаев
Поэтому проблема в самом коде
А о том, что список задекларированных в throws исключений отнюдь не исчерпывает список тех исключений, которые могут выскочить.
Верно, их может быть сколько угодно, хоть 100500 возможных вариантов, но это ничего не меняет. Если вы знаете, что в данном, конкретном участке кода, есть потенциальная возможность поймать 6 различных типов исключений времени выполнения, то пишите код, пытаясь максимально избегать их, а не думайте о том, какое бы вам еще исключение поймать.
Тот же банальный пример с OutOfMemoryError. Допустим, имеем задачу с решетом Эратосфена до 1 млрд. Вместо того, чтобы выкручиваться наизнанку, пытаясь заставить Java выделить массив целых чисел до 1ккк и, одновременно с этим тупо обернуть это в try catch (OutOfMemoryError e) - нормальный разработчик должен спроектировать решение задачи на n-ное кол-во шард, основываясь на средних возможных ресурсах машин целевой аудитории программы.
Но, повторюсь, лично для меня перехватывать RuntimeException и иже с ними - признак дурного тона, ибо это показатель некомпетентности разработчика, пытающегося «заглушить» последствия, вместо того, чтобы найти и устранить причину непосредственно в самом коде
Давно хочу спросить - говоришь ты много, гладко и правильно, а сам-то реальный код пишешь? Или Java couach?
Сейчас проектирую систему сквозной бизнес-аналитики (типа Roistat), где как раз нужен добротный анализ целевой аудитории. Я работаю в коммерц. сфере, поэтому извини, но никакого кода я тебе не запилю сюда.
Давно хочу спросить - говоришь ты много, гладко и правильно, а сам-то реальный код пишешь
В большинстве своем проектирую, но бывает и код пишу.
Я начинал работать в далеком 2010 в Екатеринбурге, в задохлых web-конторах, таких как Menocom. Проработав всего два года начальником отдела разработки, я повстречал довольно много разработчиков (конечно, в основном это PHP головного мозга, но есть и Питонисты), которые просто помешаны на концепции кинь исключение - поймай исключение. Да, это по большей своей части студенты, но некоторые из них писали специально так, чтобы придумывать кучи своих ненужных иерархий исключений. Не знаю, может кому-то это по приколу было. Я лично этого так же не понимаю.
Ну уж извиняйте, мне всего 23 года, начал работать с 18 лет, сразу как покинул родные края, а «баловаться программированием» начал с 13-ти.
Да, для вас конечно такие цифры явно не показатель, у вас то ведь опыт по 20-30 лет у всех, но знаете, мне хватает, я не жалуюсь. Выше своей головы я прыгать не стараюсь, по крайней мере.
К тому, что если будете в здешних краях Урала, можем накатить по паре пивка :)
Если что-то не нравится, извиняйте, ухожу их темы. Я ЛОР читаю давно, уже уяснил что с «бывалыми» лучше не препираться. Поэтому я пойду, оке?
В Интернетах выяснять это практически не имеет смысла.
Но речь о другом. Вот вы написали:
то пишите код, пытаясь максимально избегать их, а не думайте о том, какое бы вам еще исключение поймать
Я не понял, о чем вы ведете речь. Думал, что вы объясните. Вместо этого вы стали перечислять свой опыт. Это, к сожалению, не является пояснением вашей точки зрения.
Нет. Ну или я не понял.
Как раз таки размещение в памяти очень большого массива имеет смысл обернуть в try-catch и поймать OutOfMemoryError дабы преобразовать его в более вменяемое прикладное исключение, скажем, NotEnoughResourcesException.
Так что пример уже неудачный. А когда он дополняется фразами: «спроектировать решение задачи на n-ное кол-во шард, основываясь на средних возможных ресурсах машин целевой аудитории программы» то складывается ощущение, что я богатый клиент, которому ушлый продавец хочет впарить что-то ненужное под завесой красивых фраз из умных слов.
Хорошо, возьмем другой пример. Берем IllegalArgumentException.
И, допустим, у нас есть 2 ситуации:
Неинициализированный объект.
Выход за пределы массива.
Так вот, моя точка зрения «не ловить все что попадя» заключается в том, что первую ситуацию (неинициализированный объект) следует обрабатывать, т.к. ваше приложение может быть сервисом, которым пользуется не гик, а среднестатистический разработчик. Именно поэтому, мне в параметр метода могут передать null вместо объекта, и я должен буду обработать такую ситуацию (тем же IllegalArgumentException, допустим)
public SomeObjectOne SomeMethod(SomeObjectTwo obj) {
if (rect == null) {
throw new IllegalArgumentException("bla-bla-bla");
}
// ...
}
Т.к. по моему мнению это находится в зоне риска использования сервиса.
Но вот вторую ситуацию (выход за пределы массива) в своем сервисе я обрабатывать не буду, ибо (еще раз - это мое личное ИМХО, я не претендую на правильность) для меня эта ситуация не находится в зоне риска использования сервиса. Она находится в зоне риска самого сервиса, поэтому я могу ее исключить непосредственно в коде, не прибегая ни каким избыточным исключениям (допустим, любой элементарной проверкой).
Теперь ясно что я подразумевал под
то пишите код, пытаясь максимально избегать их, а не думайте о том, какое бы вам еще исключение поймать
Как раз таки размещение в памяти очень большого массива имеет смысл обернуть в try-catch и поймать OutOfMemoryError дабы преобразовать его в более вменяемое прикладное исключение, скажем, NotEnoughResourcesException.
Я думаю, имеется в виду «если надо уметь обрабатывать данные, которые могут не поместиться в память одного узла, нужно делать шарды, которые гарантированно поместятся в память, а не определять объем доступной памяти динамически».
Нет. Ваш последний пример был более-менее понятен, но своими объяснениями вы его только усложнили. Как по мне, все гораздо проще: если дергая SomeMethod вы знаете, что делать с IllegalArgumentException, то вы это исключение перехватываете. Если не знаете, не перехватываете. Все ваши выделенные жирным зоны риска здесь не при чем.
Ну, царь считает анскильными лалками нас всех, без исключений.
Ну а теперь вы, скорее всего, будете считать меня анскилом только потому что я мало «пишу кода». И какая ж тут разница?
Посему уж лучше царь, я хоть на фоне вас буду таким же среднестатистическим неосилятором, всяко приятнее будет :)
man Fragile Base Class problem, «синтаксическая и семантическая хрупкость базового класса» (с) Клеменс Шипёрски, «компонентно-ориентированное программирование», «stable API considered harmful» (c) Линус Троллололльвальдс
ещё в SML/NJ неплохая — с модулями в виде структур, сигнатур и функторов, и функциональными объектами поверх таких вот модулей.
Ну а теперь вы, скорее всего, будете считать меня анскилом
Чтобы я считал кого-то анскильной лалкой, этот кто-то должен сильно постараться. А пока я просто считаю, что ты склонен выражаться слишком цветисто для прогера.