Почему NullPointerException является исключением времени выполнения, а RemoteException - нет? - PullRequest
10 голосов
/ 21 мая 2010

Возможная причина того, что исключение NullPointerException является исключением времени выполнения, заключается в том, что каждый метод может его выбросить, поэтому у каждого метода должно быть «throws NullPointerException», и это будет ужасно. Но это происходит с RemoteException.

И возможная причина, по которой RemoteException не является исключением времени выполнения, состоит в том, чтобы сказать ему, что клиент должен обработать исключение. Но каждый метод в удаленной среде должен выбрасывать его, поэтому нет никакой разницы в том, чтобы выбрасывать NullPointerException.

Спекуляции? Я был чист?

Ответы [ 4 ]

18 голосов
/ 21 мая 2010

Я не буду обсуждать решение, я просто процитирую объяснение решения от Энн Воллрат (которая возглавляет разработку и реализацию Java RMI). Это извлечено из этого сообщения из архивов RMI-USERS (сообщение от января 1999 г.):

Решение сделать RemoteException проверено исключение и требует удаленного методы для перечисления исключения в его пункт о метаниях не является религиозным. Решение основано на том, как сделать Распределенные вычисления надежны. это вопрос возникает каждый раз в пока в нашем списке пользователей. у меня есть подробный ответ, который я разместил некоторое время назад Вот если вы интересно. Я не мог найти это в архив rmi-users, поэтому я его включил ниже.

ура

- Энн


Я хотел бы обратиться к обоснованию делая RemoteException проверенным Исключение, а не RuntimeException.

1) сети не надежны

Хотелось бы, чтобы они были, но на самом деле, они не. Каждая сеть имеет переходные сбои. Вы можете встроить избыточность сети, но факт что в большинстве сетей этого нет. Интранет имеет временные сбои, как делает интернет. Итак, каждый RPC сделан, подвержен неудаче. Типы неудачи могут не иметь ничего общего с «сетью» как таковой; если твой на сервере заканчиваются файловые дескрипторы, ваш клиент получит соединение исключение. Это не сеть провал, в смысле сети быть сломленным; ваш сервер находится в переходное состояние ресурса голодали.

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

2) Ошибка RPC не может быть скрыта от клиент

Частичный сбой является фактом распределенное программирование; эти неудачи не могут быть скрыты программа. Ошибка обнаруживается в клиент, является ли исключение проверено или не отмечено исключение, это все еще появляется Итак, как такое сбои указывать клиенту?

3) проверенные исключения способствуют более надежные программы

Было время, когда Дуб и ранней версии Java не было проверенные исключения. Обработка исключений был консультативный, и это было небезопасно Мир там. Это была наша группа (Джим Уолдо и я в частности :-) что рекомендуется, чтобы были исключения проверено компилятором. Джим был довольно убедительным в своих аргументах, рассказывая мира, где надежный код будет править. После некоторого рассмотрения Java был переоборудован, чтобы проверить исключения. Только те исключения для который не было восстановления или отражения ошибки приложения не будут проверены (например, OutOfMemoryError, NullPointerException соответственно). И мир снова стал безопасным.

Вообразите сюрприз инженеров Java когда много исключений в Java API и компилятор были изменены с снят, чтобы проверено, и компилятор провели различие, они обнаружены ошибки в реализации! Итак, лучшие усилия по обработке ошибок условия, какими бы благими намерениями они ни были, не было достаточно хорошо. Этот компилятор полезно для чего-то: -)

4) RemoteException следует проверять исключение

Ладно, вернёмся к делу. Так как RemoteException - это факт жизни в Вызов RPC (см. № 1, № 2) и проверка исключения заставляют вас писать безопасно код (# 3), мы думали, что делая RemoteException проверенное исключение была хорошая идея. Надежное письмораспределенные программы достаточно сложны, без компилятора, чтобы помочь Вы с исключениями.

Так, некоторые могут утверждать, что RemoteException похож на OutOfMemoryError; ваша программа должна упасть замертво, если удаленный вызов не удается. Я не согласен с этим пунктом. Да, в в некоторых случаях восстановление не происходит RemoteException; но если вы написание надежного распределенного программа, ваш клиент должен поймать неудачи и повторите попытку соответственно. Возможно, вам нужно связаться с другим сервер, или прервать транзакцию некоторых Сортировать. Если RemoteException не является обработанный, он просачивается и сбой вашего клиента (юк).

Другие заявили, что есть некоторые удаленные интерфейсы, которые используются в как локальный корпус, так и удаленный дело и клиент не должен иметь дело с исключениями в местном случай, поэтому RemoteException не должен должны быть в оговорке бросков и обращение с ним не должно быть обязательным. Теперь, если мы разрешили удаленный интерфейс методы для исключения RemoteException и имел "Rmic" переключатель для создания заглушек что бы бросить непроверенный RemoteException, клиент имеет нет Выбор в этом вопросе. Решение обработка исключений должна оставаться с клиент. Если вы определяете интерфейс это только бросает непроверенные исключения Вы никогда не сможете написать клиента, который хочет помочь компилятору справиться с эти исключения. Мы уже Из приведенного выше примера видно, что проверенные исключения воспитывает Код.

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

Установка RemoteException в каждом пункт бросков может показаться болью, но это цена, чтобы заплатить за написание надежные распределенные приложения.

- Энн Воллрат

4 голосов
/ 21 мая 2010

Потенциал для NullPointerException гораздо больше, чем RemoteException. Любой код, который вызывает метод объекта (имеется в виду практически любой код Java), потенциально может выдать NullPointerException. Только код RMI может выдать RemoteException. Это небольшое подмножество "всего кода".

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

2 голосов
/ 21 мая 2010

Я так понимаю:

  • RuntimeExceptions генерируется для вещей, которые можно было предотвратить.
  • Исключения создаются для вещей, которые нельзя было предотвратить, но можно было восстановить
  • Ошибки выдаются за вещи, которые были не поддающимися проверке и не поддающимися восстановлению.

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

0 голосов
/ 21 мая 2010

Помимо RemoteException, применяемого только к коду из пакетов java.rmi и javax.rmi (и их подпакетов), RemoteException - это тип IOException, очень похожий на SocketException is ... и все IOException s - проверенные исключения.

...