Надеюсь, вы найдете это полезным.
HTML:
<html>
<head>
<link rel = "stylesheet" href = "test.css">
<body>
</body>
<script src = "test.js"></script>
</head>
</html>
JAVASCRIPT:
var tableString = "<table>",
body = document.getElementsByTagName('body')[0],
div = document.createElement('div');
for (row = 1; row < 101; row += 1) {
tableString += "<tr>";
for (col = 1; col < 11; col += 1) {
tableString += "<td>" + "row [" + row + "]" + "col [" + col + "]" + "</td>";
}
tableString += "</tr>";
}
tableString += "</table>";
div.innerHTML = tableString;
body.appendChild(div);
То, что имеет смысл для такой библиотеки, как Spring MVC, которая должна быть достаточно открытой, чтобы соответствовать всем видам различных вариантов использования, не обязательно имеет смысл для вас при написании конкретного приложения. . Это один из таких случаев.
Если вы имеете в виду такие классы, как интерфейс Controller
, который является сигнатурой метода, например
handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception
, то это вероятно потому, что с точки зрения классов Spring, которые в ваш контроллер (например, DispatcherServlet
), им все равно, какой тип исключения вызывает ваш код - код библиотеки, такой как DispatcherServlet
, должен знать только, что этот класс может вызывать Exception и, следовательно, может обрабатывать Exception в общем случае.
Другими словами, DispatcherServlet
не выполняет ' Не нужно знать, какие именно типы исключений может генерировать ваш контроллер - он будет рассматривать любой из них как «ошибку». Вот почему сигнатура метода вызывает исключение
.
Теперь авторы API могли бы использовать в сигнатуре пользовательский тип исключения как SpringMvcException
, но это будет иметь только эффект вынудить вас обрабатывать любые проверенные типы исключений в вашем методе handleRequest
и просто обернуть их, что является утомительным стандартным кодом для создания работы. Итак, поскольку почти все, что есть в Spring, спроектировано так, чтобы сделать его максимально простым и легким для интеграции, им проще указать, что метод интерфейса просто выдает исключение
.
вызывает исключение
.
Теперь авторы API могли бы использовать в сигнатуре пользовательский тип исключения как SpringMvcException
, но это будет иметь только эффект вынудить вас обрабатывать любые проверенные типы исключений в вашем методе handleRequest
и просто обернуть их, что является утомительным стандартным кодом для создания работы. Итак, поскольку почти все, что есть в Spring, спроектировано так, чтобы сделать его максимально простым и легким для интеграции, им проще указать, что метод интерфейса просто выдает исключение
.
вызывает исключение
.
Теперь авторы API могли бы использовать в сигнатуре пользовательский тип исключения как SpringMvcException
, но это будет иметь только эффект вынудить вас обрабатывать любые проверенные типы исключений в вашем методе handleRequest
и просто обернуть их, что является утомительным стандартным кодом для создания работы. Итак, поскольку почти все, что есть в Spring, спроектировано так, чтобы сделать его максимально простым и легким для интеграции, им проще указать, что метод интерфейса просто выдает исключение
.
SpringMvcException
, но это привело бы только к тому, что вы заставили бы вас обрабатывать любые проверенные типы исключений в вашем методе handleRequest
и просто обернуть их, что является утомительным шаблоном кода для работы. Итак, поскольку почти все, что есть в Spring, спроектировано так, чтобы сделать его максимально простым и легким для интеграции, им проще указать, что метод интерфейса просто выдает исключение
. авторы API могли бы заставить подпись использовать настраиваемый тип исключения как SpringMvcException
, но это привело бы только к тому, что вы заставили бы вас обрабатывать любые проверенные типы исключений в вашем методе handleRequest
и просто обернуть их, что является утомительным шаблоном кода для работы. Итак, поскольку почти все, что есть в Spring, спроектировано так, чтобы сделать его максимально простым и легким для интеграции, им проще указать, что метод интерфейса просто выдает исключение
. Сложно.
В идеале указание исключения является частью контракта, сообщая пользователю, какие исключения могут ожидаться. Это помогает им решить, что обрабатывать, а что нет.
Хотя при написании фреймворка или библиотеки сказать невозможно -
abstract T func (...) выдает A, B, C;
потому что любой класс, расширяющий контейнер func (...), может потенциально переопределить и func.
Мне самому пришлось использовать более свободную спецификацию 'throws Exception', но, как правило,
Я действительно удалил проверенные исключения из компилятора.
Это работает лучше, чем можно было бы предположить.
Прямо сейчас значительная часть ошибок конфигурации проявляется как необработанные исключения, но при чтении первая строка текста делает реальную проблему очевидной.
Я планировал изменить обработчик исключений верхнего уровня, чтобы отображать окно сообщения об ошибке, а не поле необработанного исключения для пары типов исключений (в основном IOException). У меня уже есть исключение ErrorMessage, которое он проверяет.
Создание исключения также может вызвать множество проблем с управлением транзакциями в J2EE. Использование исключения отлова - чистое зло!
Я не награждаю вас котятами!
In my opinion yes, because this allows you to throw any exception you want.
As your program grows, you might need to throw a different exception than you had originally thought about. If you defined each individual exception type, you would have to modify the methods signature and in turn modify all methods that called it to properly process the new exception.
Just using 'throws Exception' allows any method calling your method to properly handle any methods you have listed, but whenever you add new exceptions into your function, it won't break these other methods. (Though you should probably update them to handle the new exception, but this is not required.)
Да и нет. да, «удобно» просто выбросить или перехватить одно исключение и все готово, но это действительно мешает вам при любой попытке изящного восстановления после исключения. С некоторыми исключениями можно и нужно обращаться аккуратно, чтобы ваша программа не умерла ужасной смертью. Если метод просто выдает исключение, я понятия не имею, что пошло не так, и поэтому у меня нет никакой надежды исправить и восстановить проблему.
Одна из возможных ошибок и решений:
при синтаксическом анализе целых чисел - NumberFormatException
. У нас может быть значение по умолчанию
Нижняя строка,
Брайан Гетц затрагивает некоторые из этих проблем здесь . Также см. Эффективная Java 2-е издание, автор Джош Блох. Он посвящает исключениям целый раздел. Кроме того, Род Джонсон, основатель Spring Framework, подробно описывает свои мысли об обработке исключений Java в Проектирование и разработка J2EE . Вы можете согласиться или не согласиться с его философией обработки исключений, но, по крайней мере, это может иметь больше смысла, почему они приняли такие решения.
(источник: sun.com )
ИМХО, все обсуждения и рекомендации по дизайну говорят хорошие вещи о том, что нужно делать В ОБЩЕМ, и у них есть принцип, который их поддерживает. Но обычно эти рекомендации не применимы ко всем случаям.
В случае обработки исключений идея использования проверенных исключений заключается в том, что обычно полезно перехватывать и управлять исключением по-разному, в зависимости от того, что вы хотите. Но, если вы уверены, что все они будут пойманы и обработаны одинаково, нет смысла постоянно проверять типы.
Нет.
Выдача исключения заставляет вызывающий код перехватить исключение, чего они, вероятно, не захотят делать по разным причинам.
Вот проблема с генерированием определенных исключений ... Предположим, кто-то расширяет ваш класс и хочет переопределить ваш метод. Предположим, их новая реализация должна генерировать исключение другого типа. (Как вы когда-нибудь сможете предсказать, какие исключения может потребоваться выбросить переопределяющий метод?) Человек, пишущий переопределяющий метод, имеет только два варианта: 1) обработать исключение самостоятельно (вероятно, плохой выбор) или 2) обернуть реальное исключение в одном из допустимых типов исключений и повторно выбросить.
Но вариант 2 имеет две проблемы. Во-первых, когда вы сбрасываете свои исключения в файлы журнала, вы получаете длинные уродливые цепочки вложенных исключений. Что еще более важно, вы потеряете способность перехватывать определенные исключения. Например, предположим, что переопределяющий метод вызывает другой метод, который общается с базой данных и генерирует исключение DeadlockException, если результирующий SQL вызвал взаимоблокировку. Метод переопределения должен перехватить это исключение, заключить его в один из допустимых типов и повторно вызвать. Это делает невозможным перехват и обнаружение исключения DeadlockException для кода, расположенного дальше по стеку.
Ваш вопрос в конечном итоге становится самой сутью дискуссии о проверенных и непроверенных исключениях. Вы можете погуглить и найти множество аргументов для обеих сторон спора. Я думаю, что в конечном счете, если вы верите в проверенные исключения, вы должны очень четко указывать, какие исключения генерирует метод. Если вам не нравятся проверенные исключения, вы должны объявить каждый метод, который генерирует исключение. Я попадаю в последний лагерь.
Кстати, для людей, которым не нравятся отмеченные исключения, я не люблю Мне нравится идея использования RuntimeException повсюду. Проблема в том, что вам, вероятно, потребуется включить стороннюю библиотеку, которая использует Exception, а не RuntimeException. Затем ваш код должен будет перехватить все исключения из библиотеки и обернуть их в RuntimeException. Это создает беспорядок.
Итак, если бы я снова начинал проект Java с нуля, я бы просто объявил, что каждый метод генерирует исключение.
Вам необходимо различать общий код и более конкретный код.
Рассмотрим возвращаемые типы функций в качестве аналогии. Если вы пишете такой класс, как «ArrayList», вы хотите, чтобы он был очень общим, поэтому параметры и возвращаемые значения часто являются общими »
Клинт Миллер поднимает важный вопрос о незнании того, как класс может быть расширен. Я признаю, что это проблема с конкретизацией ваших исключений. Но переход оттуда к «просто сделать все универсальным исключением» - это слишком легко сдаться. Это все равно, что сказать, что, поскольку кто-нибудь когда-нибудь может расширить нашу функцию getRetiredEmployees, чтобы в некоторых случаях возвращать EmployeeSpouse вместе с Employee, мы должны просто отказаться и сделать возвращаемый тип Object. Если это код, который вы используете внутри себя и контролируете, это не проблема: если вам нужно добавить новое исключение в функцию, добавьте его. Если это API, который вы публикуете для всего мира, то да, проблема гораздо сложнее. Я бы сказал, что общее решение - попытаться рационально подумать, какие исключения имеют смысл, и включить их все, даже если они не все в настоящее время реализованы. Если один из ваших клиентов делает что-то совершенно неожиданное, ну что ж, это проблема, на которую нет простого ответа.
Делать все универсальным - неправильный ответ, потому что это делает все трудным для понимания, трудным для поддержания, и трудно проверить точность.
Нет, абсолютно нет. Вы должны указать, какие исключения вы собираетесь выбросить, чтобы вызывающий мог поступать правильно с каждым из них. Если вы этого не сделаете, «throws Exception» будет передан вверх по цепочке, и лучшее, что могут сделать вызывающие, - это printStackTrace () и умереть.
Обновление: чтобы противостоять некоторым возражениям «что, если я отменю метод», Я бы пошел немного дальше и сказал, что каждый раз, когда у вас есть пакет, который генерирует исключения (в отличие от передачи исключения от вызывающей стороны), вы должны объявить класс исключения в этом пакете. Таким образом, если вы переопределяете мой "addToSchedule () throws ScheduleConflictException", вы вполне можете создать подкласс ScheduleConflictException, чтобы делать то, что вам нужно.
Список всех исключений. Таким образом:
* Четко определено, что МОЖЕТ пойти не так.
* Пользователи вашего класса могут ТОЧНО знать, какие исключения они должны обрабатывать.
Кроме того, замещающий метод должен делать то же самое, что и замещаемый, но другим способом. Следовательно, как у вас могло быть другое исключение, которое НЕ ЯВЛЯЕТСЯ подклассом уже созданного исключения? Вы не должны. Кроме того, вам НЕ СЛЕДУЕТ генерировать новые исключения в подклассе, поскольку подкласс должен быть в состоянии заменить его родительский класс, следовательно, если он передается как «p» в
public void method(Parent p);
, как «метод» узнает, что он должен обрабатывать какое-то новое исключение? В этом не должно быть необходимости. А это означает неправильный дизайн (либо родительского класса, либо подкласса).
ИМО, самая большая причина для того, чтобы не генерировать исключение, заключается в том, что оно заставляет наших клиентов перехватить (Исключение e)
, если они действительно заинтересованы в каких-либо действиях.
Проблема с перехватом (Exception e)
заключается в том, что Exception при установленном флажке также является суперклассом RuntimeException и поэтому заставляет клиента перехватить все RuntimeExceptions ] тоже.
К сожалению, здесь нет техники catch (CheckedException e). Предполагая, что ваш бедный клиент не нуждался в перехвате исключений RuntimeExceptions, он должен выполнить проверку instanceof и повторно выбросить его, если это исключение RuntimeException.
также является суперклассом RuntimeException и поэтому заставляет клиента перехватывать все исключения RuntimeException .К сожалению, здесь нет техники перехвата (CheckedException e). Предполагая, что ваш бедный клиент не нуждался в перехвате исключений RuntimeExceptions, он должен выполнить проверку instanceof и повторно выбросить его, если это исключение RuntimeException.
также является суперклассом RuntimeException и поэтому заставляет клиента перехватывать все исключения RuntimeException .К сожалению, здесь нет техники перехвата (CheckedException e). Предполагая, что ваш бедный клиент не нуждался в перехвате исключений RuntimeExceptions, он должен выполнить проверку instanceof и повторно выбросить его, если это исключение RuntimeException.