что нужно делать программисту если в коде происходит деление на ноль java
Исключения
В методе, в котором происходит ошибка, создаётся и передаётся специальный объект. Метод может либо обработать исключение самостоятельно, либо пропустить его. В любом случае исключение ловится и обрабатывается. Исключение может появиться благодаря самой системе, либо вы сами можете создать его вручную. Системные исключения возникают при неправильном использовании языка Java или запрещённых приёмов доступа к системе. Ваши собственные исключения обрабатывают специфические ошибки вашей программы.
Вернёмся к примеру с делением. Деление на нуль может предотвратить проверкой соответствующего условия. Но что делать, если знаменатель оказался нулём? Возможно, в контексте вашей задачи известно, как следует поступить в такой ситуации. Но, если нулевой знаменатель возник неожиданно, деление в принципе невозможно, и тогда необходимо возбудить исключение, а не продолжать исполнение программы.
Существует пять ключевых слов, используемых в исключениях: try, catch, throw, throws, finally. Порядок обработки исключений следующий.
Операторы программы, которые вы хотите отслеживать, помещаются в блок try. Если исключение произошло, то оно создаётся и передаётся дальше. Ваш код может перехватить исключение при помощи блока catch и обработать его. Системные исключения автоматически передаются самой системой. Чтобы передать исключение вручную, используется throw. Любое исключение, созданное и передаваемое внутри метода, должно быть указано в его интерфейсе ключевым словом throws. Любой код, который следует выполнить обязательно после завершения блока try, помещается в блок finally
Схематически код выглядит так:
Существует специальный класс для исключений Trowable. В него входят два класса Exception и Error.
Класс Exception используется для обработки исключений вашей программой. Вы можете наследоваться от него для создания собственных типов исключений. Для распространённых ошибок уже существует класс RuntimeException, который может обрабатывать деление на ноль или определять ошибочную индексацию массива.
Класс Error служит для обработки ошибок в самом языке Java и на практике вам не придётся иметь с ним дело.
Прежде чем научиться обрабатывать исключения, нам (как и нормальному любопытному коту) хочется посмотреть, а что происходит, если ошибку не обработать. Давайте разделим число котов в вашей квартире на ноль, хотя мы и знаем, что котов на ноль делить нельзя!
Я поместил код в обработчик щелчка кнопки. Когда система времени выполнения Java обнаруживает попытку деления на ноль, она создаёт объект исключения и передаёт его. Да вот незадача, никто не перехватывает его, хотя это должны были сделать вы. Видя вашу бездеятельность, объект перехватывает стандартный системный обработчик Java, который отличается вредных характером. Он останавливает вашу программу и выводит сообщение об ошибке, которое можно увидеть в журнале LogCat:
Как видно, созданный объект исключения принадлежит к классу ArithmeticException, далее системный обработчик любезно вывел краткое описание ошибки и место возникновения.
Вряд ли пользователи вашей программы будут довольны, если вы так и оставите обработку ошибки системе. Если программа будет завершаться с такой ошибкой, то скорее всего вашу программу просто удалят. Посмотрим, как мы можем исправить ситуацию.
Поместим проблемный код в блок try, а в блоке catch обработаем исключение.
Теперь программа аварийно не закрывается, так как мы обрабатываем ситуацию с делением на ноль.
В данном случае мы уже знали, к какому классу принадлежит получаемая ошибка, поэтому в блоке catch сразу указали конкретный тип. Обратите внимание, что последний оператор в блоке try не срабатывает, так как ошибка происходит раньше строчкой выше. Далее выполнение передаётся в блок catch, далее выполняются следующие операторы в обычном порядке.
Операторы try и catch работают совместно в паре. Хотя возможны ситуации, когда catch может обрабатывать несколько вложенных операторов try.
Если вы хотите увидеть описание ошибки, то параметр e и поможет увидеть ёго.
По умолчанию, класс Trowable, к которому относится ArithmeticException возвращает строку, содержащую описание исключения. Но вы можете и явно указать метод e.toString.
Несколько исключений
Фрагмент кода может содержать несколько проблемных мест. Например, кроме деления на ноль, возможна ошибка индексации массива. В таком случае вам нужно создать два или более операторов catch для каждого типа исключения. Причём они проверяются по порядку. Если исключение будет обнаружено у первого блока обработки, то он будет выполнен, а остальные проверки пропускаются и выполнение программы продолжается с места, который следует за блоком try/catch.
В примере мы добавили массив с тремя элементами, но обращаемся к четвёртому элементу, так как забыли, что отсчёт у массива начинается с нуля. Если оставить значение переменной zero равным нулю, то сработает обработка первого исключения деления на ноль, и мы даже не узнаем о существовании второй ошибки. Но допустим, что в результате каких-то вычислений значение переменной стало равно единице. Тогда наше исключение ArithmeticException не сработает. Но сработает новое добавленное исключение ArrayIndexOutOfBoundsException. А дальше всё пойдёт как раньше.
Тут всегда нужно помнить одну особенность. При использовании множественных операторов catch обработчики подклассов исключений должные находиться выше, чем обработчики их суперклассов. Иначе, суперкласс будет перехватывать все исключения, имея большую область перехвата. Иными словами, Exception не должен находиться выше ArithmeticException и ArrayIndexOutOfBoundsException. К счастью, среда разработки сама замечает непорядок и предупреждает вас, что такой порядок не годится. Увидев такую ошибку, попробуйте перенести блок обработки исключений ниже.
Вложенные операторы try
Операторы try могут быть вложенными. Если вложенный оператор try не имеет своего обработчика catch для определения исключения, то идёт поиск обработчика catch у внешнего блока try и т.д. Если подходящий catch не будет найден, то исключение обработает сама система (что никуда не годится).
Оператор throw
Часть исключений может обрабатывать сама система. Но можно создать собственные исключения при помощи оператора throw. Код выглядит так:
Вам нужно создать экземпляр класса Throwable или его наследников. Получить объект класса Throwable можно в операторе catch или стандартным способом через оператор new.
Мы могли бы написать такой код для кнопки:
Мы объявили объект класса Cat, но забыли его проинициализировать, например, в onCreate(). Теперь нажатие кнопки вызовет исключение, которое обработает система, а в логах мы можем прочитать сообщение об ошибке. Возможно, вы захотите использовать другое исключение, например, throw new UnsupportedOperationException(«Котик не инициализирован»);.
В любом случае мы передали обработку ошибки системе. В реальном приложении вам нужно обработать ошибку самостоятельно.
Поток выполнения останавливается непосредственно после оператора throw и другие операторы не выполняются. При этом ищется ближайший блок try/catch соответствующего исключению типа.
Перепишем пример с обработкой ошибки.
Мы создали новый объект класса NullPointerException. Многие классы исключений кроме стандартного конструктора по умолчанию с пустыми скобками имеют второй конструктор с строковым параметром, в котором можно разместить подходящую информацию об исключении. Получить текст из него можно через метод getMessage(), что мы и сделали в блоке catch.
Теперь программа не закроется аварийно, а будет просто выводить сообщения в всплывающих Toast.
Оператор throws
Если метод может породить исключение, которое он сам не обрабатывает, он должен задать это поведение так, чтобы вызывающий его код мог позаботиться об этом исключении. Для этого к объявлению метода добавляется конструкция throws, которая перечисляет типы исключений (кроме исключений Error и RuntimeException и их подклассов).
Общая форма объявления метода с оператором throws:
В фрагменте список_исключений можно указать список исключений через запятую.
Создадим метод, который может породить исключение, но не обрабатывает его. А в щелчке кнопки вызовем его.
Если вы запустите пример, то получите ошибку. Исправим код.
Мы поместили вызов метода в блок try и вызвали блок catch с нужным типом исключения. Теперь ошибки не будет.
Оператор finally
Когда исключение передано, выполнение метода направляется по нелинейному пути. Это может стать источником проблем. Например, при входе метод открывает файл и закрывает при выходе. Чтобы закрытие файла не было пропущено из-за обработки исключения, был предложен механизм finally.
Ключевое слово finally создаёт блок кода, который будет выполнен после завершения блока try/catch, но перед кодом, следующим за ним. Блок будет выполнен, независимо от того, передано исключение или нет. Оператор finally не обязателен, однако каждый оператор try требует наличия либо catch, либо finally.
Встроенные исключения Java
Существуют несколько готовых системных исключений. Большинство из них являются подклассами типа RuntimeException и их не нужно включать в список throws. Вот небольшой список непроверяемых исключений.
Список проверяемых системных исключений, которые можно включать в список throws.
Создание собственных классов исключений
Система не может предусмотреть все исключения, иногда вам придётся создать собственный тип исключения для вашего приложения. Вам нужно наследоваться от Exception (напомню, что этот класс наследуется от Trowable) и переопределить нужные методы класса Throwable. Либо вы можете наследоваться от уже существующего типа, который наиболее близок по логике с вашим исключением.
Мы создали собственный класс HungryCatException, в методе testMethod() его возбуждаем, а по нажатию кнопки вызываем этот метод. В результате наше исключение сработает.
Создать класс исключения с конструктором, который получает аргумент-строку, также просто.
Ещё вариант. Добавим также метод toString().
Теперь класс содержит два конструктора. Во втором конструкторе используется конструктор родительского класса с аргументом String, вызываемый ключевым словом super.
Перехват произвольных исключений
Можно создать универсальный обработчик, перехватывающий любые типы исключения. Осуществляется это перехватом базового класса всех исключений Exception:
Подобная конструкция не упустит ни одного исключения, поэтому её следует размещать в самом конце списка обработчиков, во избежание блокировки следующих за ней обработчиков исключений.
Основные правила обработки исключений
Используйте исключения для того, чтобы:
BestProg
Генерирование исключений в лямбда-выражениях. Примеры
Содержание
Поиск на других ресурсах:
1. Особенности генерирования исключений в лямбда-выражениях
Как и в методе, в лямбда-выражении можно генерировать исключения двух видов:
2. Примеры генерирования стандартного исключения в лямбда-выражении
2.1. Деление двух чисел. Генерирование исключения деления на ноль
В примере приводится лямбда-выражение, которое возвращает результат деления двух чисел. В коде лямбда-выражения проверяется значение делителя. Если это значение равно 0, то генерируется стандартное исключение ArithmeticException с соответствующим сообщением.
Результат выполнения программы
2.2. Поэлементное суммирование массивов. Шаблонный функциональный интерфейс. Генерирование исключения в лямбда-выражении. Передача лямбда-выражения в метод
Основные требования к массивам:
Лямбда-выражение должно передаваться в метод в качестве параметра. Для выполнения этого нужно объявить дополнительный класс с методом, который получает лямбда-выражение в качестве параметра.
В функции main() продемонстрировать использование лямбда-выражений для обработки исключений.
Решение. Согласно условию задачи в программе нужно ввести следующие классы и интерфейс:
Текст решения задачи приведен далее
Результат работы программы
3. Пример генерирования исключения, которое обрабатывается специально разработанным классом
Розв’язок. Текст решения задачи следующий.
После выполнения программа выдаст следующий результат
BestProg
Содержание
Поиск на других ресурсах:
1. Что такое исключительная ситуация?
Исключительная ситуация – это программная ошибка, которая возникает во время выполнения последовательности программного кода. Программная ошибка может быть логической ошибкой программиста во время разработки программы. Например, исключительная ситуация может возникать в случаях:
Правильная обработка исключений есть важным элементом написания профессиональных программ на Java.
2. Понятие исключения в языке Java
Как правило, каждая исключительная ситуация может иметь свой код ошибки и обработку этого кода (вывод соответствующих сообщений, и т.п.). В языке программирования Java разработан механизм обработки исключительных ситуаций.
В языке программирования Java, исключение – это специальный объект, описывающий исключительную ситуацию, которая возникла в некоторой части программного кода. Объект представляющий исключение, генерируется в момент возникновения исключительной ситуации. После возникновения критической (исключительной) ситуации исключение перехватывается и обрабатывается. Таким образом, возникает понятие генерирования исключения. Генерирование исключения – процесс создания объекта, который описывает данное исключение.
3. Какими способами могут генерироваться исключения?
В языке Java исключения могут генерироваться одним из двух способов:
4. В каких случаях вызывается стандартный обработчик исключений Java?
Стандартный обработчик исключений Java вызывается в случаях, когда программа:
Если программа содержит собственный код try…catch для обработки данной исключительной ситуации, тогда стандартный обработчик исключений не вызывается.
5. Какие ключевые слова используются для обработки исключений в Java?
Для обработки исключений в Java используются следующие ключевые слова:
В языке Java можно вручную перехватывать исключения (исключительные ситуации) и соответствующим образом обрабатывать их. Важно, чтобы при возникновении исключительной ситуации программа не прекратила свое выполнение.
В блоке try размещаются операторы программы, которые нужно проконтролировать и, в случае возникновения исключительной ситуации, сгенерировать исключение. Внутри блока try могут быть вызваны различные методы, способные сгенерировать то или иное исключение. Однако, обработчик исключения будет только один.
Операторы try и catch составляют единое целое. Оператор finally может отсутствовать.
7. Пример генерирования исключения и его перехват стандартным обработчиком исключений Java
Если в программе отсутствует собственный блок try…catch перехвата исключения, будет вызван стандартный обработчик исключения. В примере демонстрируется вызов стандартного обработчика.
Текст класса DemoExceptions следующий:
Если в другом классе использовать метод DivNumbers() следующим образом
то будет вызванный стандартный обработчик Java, который выведет следующее сообщение
8. Пример перехвата и обработки исключения с помощью оператора try…catch
Текст класса DemoExceptions следующий
Теперь, при использовании метода DivNumbers2() в другом классе
система выдаст следующий результат после запуска программы на выполнение
Можно изменить вывод собственного сообщения об исключении на стандартное сообщение. В этом случае нужно изменить текст в блоке catch на следующий
После изменений, результат выполнения программы будет такой
Текст класса DemoExceptions следующий
будет вызываться всегда. И перед оператором
Использование метода DivNumbers3() в другом классе может быть следующим
Результат выполнения программы
10. Как реализовать вывод описания исключения? Пример
В результате программа будет выводить следующий результат
11. Пример перехвата нескольких исключительных ситуаций (несколько операторов catch )
Реализация класса DivArrays следующая
Использование класса в другом программном коде
Исключения в Java
Обработка исключительных ситуаций (exception handling) — механизм языков программирования, предназначенный для описания реакции программы на ошибки времени выполнения и другие возможные проблемы (исключения), которые могут возникнуть при выполнении программы и приводят к невозможности (бессмысленности) дальнейшей отработки программой её базового алгоритма.
Синтаксис
Здесь в методе getAreaValue мы бросаем исключение IllegalArgumentException с помощью ключевого слова throw. В данном случае в сигнатуре метода отсутствует throws IllegalArgumentException, это не сделано потому что исключение IllegalArgumentException является не проверяемым, о них мы ещё поговорим.
Общий вид конструкции для «поимки» исключительной ситуации выглядит следующим образом:
В нашем случае для площади прямоугольника:
Здесь мы поймали IllegalArgumentException и залогировали данное событие. Дело в том что «починить» такую поломку мы не можем, не будем же мы угадывать что хотел пользователь :). По этому мы пробрасываем данное исключение дальше с помощью «throw e;». Такое часто можно встретить на серверах приложений(веб-серверах).
finally
Иногда требуется гарантировать, что определенный участок кода будет выполняться независимо от того, какие исключения были возбуждены и перехвачены. Для создания такого участка кода используется ключевое слово finally. Даже в тех случаях, когда в методе нет соответствующего возбужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try. У каждого раздела try должен быть по крайней мере или один раздел catch или блок finally. Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода. Ниже приведен пример класса с двумя методами, завершение которых происходит по разным причинам, но в обоих перед выходом выполняется код раздела finally.
В этом примере в методе procA из-за возбуждения исключения происходит преждевременный выход из блока try, но по пути «наружу» выполняется раздел finally. Другой метод procB завершает работу выполнением стоящего в try-блоке оператора return, но и при этом перед выходом из метода выполняется программный код блока finally. Ниже приведен результат, полученный при выполнении этой программы.
Иерархия исключений
Все классы обрабатывающие ошибки являются наследниками класса java.lang.Throwable. Только объекты этого класса или его наследников могут быть «брошены» JVM при возникновении какой-нибудь исключительной ситуации, а также только эти объекты могут быть «брошены» во время выполнения программы с помощью ключевого слова throw.
Прямыми наследниками класса Throwable являются Error и Exception.
При программировании на Java основное внимание следует уделять иерархии Exception. Эта иерархия также разделяется на две ветви: исключения, производные от класса RuntimeException, и остальные. Исключения типа RuntimeException возникают вследствие ошибок программирования. Все другие исключения являются следствием непредвиденного стечения обстоятельств, например, ошибок ввода-вывода, возникающих при выполнении вполне корректных программ.
Рассмотрим основные классы исключений.
Создание своих классов исключений
Хотя встроенные исключения Java обрабатывают большинство частых ошибок, вероятно, вам потребуется создать ваши собственные типы исключений для обработки ситуаций, специфичных для ваших приложений. Это достаточно просто сделать: просто определите подкласс Exception (который, разумеется, является подклассом Throwable). Ваши подклассы не обязаны реализовывать что-либо — важно само их присутствие в системе типов, которое позволит использовать их как исключения.
Обработка нескольких исключений
Одному блоку try может соответствовать сразу несколько блоков catch с разными классами исключений.
Это удобно, если обработка ошибок не отличается.
Конструкция try-with-resources
Наследование методов бросающих исключения
Можно лишь сужать класс исключения:
Как бросить проверяемое исключение не обрабатывая его (хак)
Нет ничего невозможного. С помощью рефлексии и внутреннего API языка java можно творить магию :).
В примере используется рефлексия для получения объекта Unsafe так как другими средствами это сделать проблематично. У класса Unsafe приватный конструктор. А если попытаться вызвать статический метод getUnsafe() то будет брошено исключение SecurityException.
Заключение
Изначально я хотел сделать себе шпаргалку по иерархии классов исключений и не планировал писать статью. Но получилось так, что шпаргалка выросла в статью 🙂
Надеюсь она поможет кому-нибудь перед собеседованием, или просто вспомнить/углубить знания 🙂 Спасибо за внимание!
Если Вам понравилась статья, проголосуйте за нее
Голосов: 86 Голосовать
Почему деление на ноль с плавающей запятой (или двойной точностью) числа не бросают java.ленг.ArithmeticException: / по нулю в Java
следующее заявление бросает java.lang.ArithmeticException: / by zero как очевидное.
потому что буквальный 0 считается int прямом и деление на ноль не допускается в целочисленной арифметике.
следующее утверждение производит NaN (не число) без исключение.
в этом случае оба операнда считаются двойными.
аналогично, следующие заявления не выбросить любое исключение.
они производят следующий вывод.
они все вернутся false. почему эта операция (деление на ноль) разрешена с числами с плавающей запятой или двойной точностью?
кстати, я могу понять, что числа с плавающей запятой (числа с двойной точностью) имеют свои значения, которые представляют положительная бесконечность, отрицательная бесконечность, не ( NaN ).
6 ответов
короче говоря, так это указано в стандарте IEEE-754, который является тем, что Java Операции С Плавающей Запятой основаны на.
модель 754 поощряет надежные программы. Он предназначен не только для численных аналитиков, но и для пользователи электронных таблиц, системы баз данных или даже кофейники. Правила распространения для NaNs и бесконечностей позволяют исчезать несущественным исключениям. Аналогично, постепенный underflow поддерживает свойства ошибки в диапазоне точности.
когда исключительным ситуациям нужно внимание, их можно рассмотреть немедленно через ловушки или в удобное время через флаги состояния. Ловушки можно использовать для остановки программы, но неустранимые ситуации крайне редки. Просто остановить программу нельзя опция для встроенных систем или сетевых агентов. Чаще всего ловушки регистрируют диагностическую информацию или заменяют допустимые результаты.
флаги предлагают как предсказуемый поток управления, так и скорость. Их использование требует, чтобы программист знал об исключительных условиях, но липкость флага позволяет программистам откладывать обработку исключительных условий до необходимости.
это так, потому что так определил его IEEE 754.
создание исключения похоже на (программное обеспечение) INT создается делением на ноль на x86 микропроцессоры.
до бесконечности и дальше
почему Java использует Double s для представления десятичных дробей. Двоичный файл не может полностью представлять число, он может представлять только приближение и, следовательно, не может быть двойником Java.
Также см. раздел : Специальные Значения С Плавающей Запятой at Математические Ошибки дополнительные info:)
обновление: INT не имеет бесконечности и NaN значение в наборе, тогда как float имеет бесконечность и NaN значение. (Согласно стандартам IEEE 754, которым следует java)
когда есть деление на ноль, компьютер не может создать представление результата в виде числа. Компьютер должен сигнализировать, что результат не является числом.
для значений с плавающей запятой он может создать специальное значение not-a-number sentinel, потому что есть некоторые 32-разрядные (для float ) и 64-битных (для double ) битовые шаблоны, которые не представляют число и, следовательно, могут быть интерпретированы как не-число ( NaN ).
для целых значений с использованием common двойки-схема дополнения (как требует Java), все 32-битные (для int ) и 64-битных (для long ) битовые шаблоны представляют собой количество. Таким образом, компьютер не может сообщить о проблеме с помощью sentinel. Он должен каким-то образом сообщать о проблеме «вне диапазона». Исключение-это метод out of band, выбранный для Java.
Java следует стандарту IEEE 754, который определяет значения, возвращаемые по умолчанию в случае деления на ноль. http://en.wikipedia.org/wiki/IEEE_754#Exception_handling
деление на ноль (операция с конечными операндами дает точный бесконечный результат, например, 1/0 или log (0)) (по умолчанию возвращает ±infinity).