2013-07-31 4 views
4

Так что это касается вопроса о собеседовании, о котором я недавно спросил. Интервьюер начал с этого, спросив меня, как мы создаем наши пользовательские Исключения. Отвечая на это, он спросил меня, как я создаю RunTimeExceptions. Я сказал, что мы создадим их так же, как мы создадим проверенные Исключения. Просто наше пользовательское исключение будет распространяться на класс RunTimeException. Затем он спросил, в каких сценариях вы создадите собственное исключение RunTimeException. Теперь я не мог придумать хороший ответ на этот вопрос. Ни в одном из моих проектов мы не создали пользовательские RunTimeExceptions.Пользовательские исключения RunTime

Я также считаю, что мы никогда не должны создавать RunTimeExceptions. JVM может терпеть неудачу только конечным числом способов, и она хорошо их обрабатывает. При написании приложения мы не можем предсказать, какие исключения выполнения могут возникать, и поэтому нам не нужно их обрабатывать. И если мы можем предсказать эти условия, тогда они не являются RunTimeExceptions. Поскольку нам не нужны новые исключения во время выполнения, а также необходимость обработки исключений runtime, почему нам когда-либо понадобится создать пользовательское исключение RunTimeException. Все, что мы можем предугадать как возможное условие отказа, должно быть обработано во время компиляции, и это будет проверенное исключение. Правильно? Только те вещи, которые не могут быть обработаны во время компиляции, и те, которые зависят от времени выполнения, входят в категорию RunTimeExceptions.

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

Я пропустил что-то/много вещей здесь? Прошу совета.

Thanks, Chan.

+0

Современные методы программирования рекомендуют использовать ** непроверенные ** исключения.Вы можете прочитать, почему, в хорошей статье [здесь] (http://johnpwood.net/2008/04/21/java-checked-exceptions-vs-runtime-exceptions/). – agad

ответ

6

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

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

Например, рассмотрим класс, который позволяет хранить данные в разреженном многомерном массиве. Один из API, который, вероятно, предоставит такой класс, - это getter, который принимает массив индексов. Число индексов должно быть равно числу измерений в массиве, и каждый индекс должен быть в пределах своих границ. Поставка параметра массива, который имеет неправильное количество элементов или имеет один или несколько элементов вне его границ, является ошибкой программирования. Вы должны сигнализировать об этом с помощью исключения времени выполнения. Если вы хотите сообщить об этой ошибке и предоставить полную информацию о том, что пошло не так, ваш подкласс IllegalArgumentException, подкласс RuntimeException, чтобы создать собственное исключение.

Наконец, есть еще одна ситуация, когда вы хотите подкласс RuntimeException: когда вы должны обеспечить «правильный» исключение, но вы не хотите, чтобы пользователи, чтобы обернуть каждый вызов вашего API в блоке try/catch. В таких ситуациях, вы можете заменить один метод

void performOperation() throws CustomApplicationException; 

с парой методов

boolean canPerformOperation(); 
void performOperation(); 

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

Второй метод выходит из строя только в состоянии, когда первый метод возвращает false, что приводит к ошибке при программировании, что оправдывает использование RuntimeException для сигнализации о таких отказах.

+0

Я слишком неопытен, чтобы комментировать ответы на такие легенды, как @JonSkeet или вы сэр! Но дело в том, что он может добавлять свои пользовательские сообщения в исключение времени выполнения, зачем создавать новый класс? – NINCOMPOOP

+1

@ TheNewIdiot, чтобы иметь возможность поймать его, если хотите, или легко справиться с ним по-другому – agad

+0

@agad Он может даже поймать время выполнения? Разве он не может? – NINCOMPOOP

1

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

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

Пункт на самом деле заключается в том, что вызывающий метод не должен окружать его в блоке try-catch, поскольку он не является исключением. Если у вас нет веских оснований бросать обычное исключенное исключение, скажем, просто предоставить дополнительную настраиваемую информацию для ведения журнала и т. Д., Не делайте этого. Другая неудачная реализация иногда будет заключаться в том, что вы просто захотите поймать проверенные исключения в своем коде и выбросить произвольные непроверенные исключения, чтобы избавиться от всех попыток в коде вызывающего абонента.

+1

Как он «побеждает всю цель создания настраиваемого исключения»? Мне кажется, что вы считаете, что проверка времени компиляции является единственным преимуществом создания подклассов исключений, и я не согласен с этим. –

+0

Спасибо. Я так и думал, но, так как интервьюер спросил меня об этом, и, поскольку у нас было более 5 минут обсуждения этого вопроса, я подумал, что проверю, имеет ли какое-либо из моих помещений фундаментальное недостаток или если я чего-то не вижу. – Chan

1

Вы бы создать свой собственный подкласс RuntimeException если:

  • Вы не хотите, чтобы это было проверено исключением, потому что вы не ожидаете, звонящие явно поймать исключение. (Лично я считаю, что проверенные исключения скорее используются в стандартной библиотеке.)
  • Вы по-прежнему хотите предоставить больше информации, чем просто сообщение (только сам тип является полезной отправной точкой в ​​журнале).

HibernateException - пример этого в ORM Hibernate.

+2

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

+0

@NarendraPathai: Это зависит от того, что вы подразумеваете под «обнаружением», что исключение выбрано. Я явно охватываю вызывающих абонентов, а не * ловил * исключение в первом пуле. –

4

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

Например, другой сервис вызывает мой сервер для информации о клиенте. Вход является идентификатором клиента, и я верну клиентский объект

// Web Service interface 
public CustomerInfo getCustomerInformation(int customerId, int securityToken) { 
    check(securityToken); 
    Customer customer = merchantService.getCustomer(customerId); 
    return customer.getInfo(); 
} 

// MerchantService 
public Customer getCustomer(int customerId) { 
    return customerService.getCustomer(customerId); 
} 

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

// Customer service 
public Customer getCustomer(id) { 
    Customer customer = getCustomerFromDB(); 
    if (customer == null) throw CustomerNotExistedException(); 
    return customer; 
} 

Теперь вопрос CustomerNotExistedException является ли исключение или RuntimeException. Если это проверенное исключение, вам нужно поймать и обработать его по функции, которая вызывает getCustomer. Это означает, что вы должны поймать его в MerchantService. Тем не менее, все, что вам нужно, это создать ошибку 404 на уровне WebService, так что ловли ее в MerchantService не будут делать ничего, кроме повторения исключения. Он загрязняет код.

В общем случае, я часто использую RuntimeException, чтобы исключение «пузырилось» до уровня, на котором они могут быть обработаны.

Для справки, я бы рекомендовал книгу Clean code from Robert C. Martin. Это объясняет, как мы должны использовать исключение для обработки ошибок в Java.

Смежные вопросы