Генерирование исключений в лямбда-выражениях. Примеры
Содержание
- 1. Особенности генерирования исключений в лямбда-выражениях
- 2. Примеры генерирования стандартного исключения в лямбда-выражении
- 3. Пример генерирования исключения, которое обрабатывается специально разработанным классом
- Связанные темы
Поиск на других ресурсах:
1. Особенности генерирования исключений в лямбда-выражениях
Бывают случаи, когда в лямбда-выражениях может возникнуть исключительная ситуация. В этом случае лямбда-выражение должно сгенерировать исключение. Генерирование исключения лямбда-выражением реализуется стандартным способом с помощью оператора throw. Проверяемый фрагмент в лямбда-выражении помещается в блок try-catch.
Как и в методе, в лямбда-выражении можно генерировать исключения двух видов:
- заранее определенных типов Java (ArithmeticException, ArrayIndexOutOfBoundsException и т.д.);
- собственноручно разработанных классов исключений.
⇑
2. Примеры генерирования стандартного исключения в лямбда-выражении
2.1. Деление двух чисел. Генерирование исключения деления на ноль
В примере приводится лямбда-выражение, которое возвращает результат деления двух чисел. В коде лямбда-выражения проверяется значение делителя. Если это значение равно 0, то генерируется стандартное исключение ArithmeticException с соответствующим сообщением.
// Генерирование исключений в лямбда-выражениях // Объявить функциональный интерфейс interface IDivNumbers { // Объявить метод, который делит два числа double Division(double a, double b); } // Класс, который содержит методы, реализующие лямбда-выражения и // тестируют работу программы. public class Lambda { public static void main(String[] args) { // 1. Объявить ссылку на IDivNumbers IDivNumbers ref; // 2. Реализовать лямбда-выражение, которое делит два числа и // при необходимости генерирует исключение ref = (a, b) -> { try { // Обработать проверку деления на 0 if (b==0) throw new ArithmeticException("Exception: divide by zero."); return a/b; // если b!=0, то вернуть результат деления } catch (ArithmeticException e) { System.out.println(e.getMessage()); // Вывести сообщение return 0.0; } }; // 3. Протестировать лямбда-выражение на исключительную ситуацию double res = ref.Division(5, 0); // Exception: divide by zero. // 4. Вывести результат System.out.println("res = " + res); // res = 0.0 } }
Результат выполнения программы
Exception: divide by zero. res = 0.0
⇑
2.2. Поэлементное суммирование массивов. Шаблонный функциональный интерфейс. Генерирование исключения в лямбда-выражении. Передача лямбда-выражения в метод
Условие задачи. Используя механизм лямбда-выражений реализовать поэлементное суммирование массивов обобщенного типа T. Лямбда-выражение должно обрабатывать нижеуказанные исключения, генерируемые в случае, если массивы не соответствуют заданным требованиям.
Основные требования к массивам:
- массивы должны поддерживать работу с числовыми типами;
- массивы должны иметь ненулевую длину. Если один из массивов имеет нулевую длину, то сгенерировать исключение EmptyArrayException. Для реализации исключения EmptyArrayException разработать одноименный класс;
- массивы должны иметь одинаковую длину. Если массивы имеют разную длину, то сгенерировать стандартное исключение ArrayIndexOutOfBoundsException.
Лямбда-выражение должно передаваться в метод в качестве параметра. Для выполнения этого нужно объявить дополнительный класс с методом, который получает лямбда-выражение в качестве параметра.
В функции main() продемонстрировать использование лямбда-выражений для обработки исключений.
Решение. Согласно условию задачи в программе нужно ввести следующие классы и интерфейс:
- обобщенный (шаблонный) функциональный интерфейс ISumArrays<T>, который оперирует числовым типом T. Тип интерфейса ограничивается типом Number (все числовые типы). В интерфейсе нужно определить метод SumArrays(), который получает параметром два массива и возвращает результирующий массив;
- класс EmptyArrayException, который определяет исключение, возникающее в случае, когда один из массивов имеет нулевую длину;
- класс ArrayMethod, содержащий единственный метод AddMethod(). Этот метод получает три параметра: два массива-слагаемые и лямбда-выражение в виде ссылки на ISumArrays<T>;
- класс Lambda, в котором объявляется функция main(). В функции main() создаются тестирующие массивы для различных типов и лямбда-выражение. Эти все данные передаются в метод AddMethod() экземпляра класса ArrayMethod.
Текст решения задачи приведен далее
// Генерирование исключений в лямбда-выражениях // Объявить обобщенный функциональный интерфейс, // который оперирует типом T. Тип T ограничивается числовыми типами (Number). interface ISumArrays<T extends Number> { // Метод, получающий два массива и возвращающий массив T[] SumArrays(T[] array1, T[] array2); } // Класс, определяющий исключение, которое возникает, когда один // из массивов имеет нулевую длину. Класс должен быть унаследован // от класса Exception class EmptyArrayException extends Exception { // Конструктор класса EmptyArrayException(String message) { super(message); // вызвать конструктор суперкласса } } // Обобщенный класс, содержащий метод, в который передается лямбда-выражение. // Для суммирования элементов метод вызывает другой метод SumArrays() интерфейса ISumArrays. class ArrayMethod<T extends Number> { // Метод, получающий лямбда-выражение в качестве параметра public T[] AddMethod(T[] array1, T[] array2, ISumArrays<T> ref) { T[] array3 = null; array3 = ref.SumArrays(array1, array2); // вернуть сумму массивов return array3; } } // Класс, содержащий методы, которые реализуют лямбда-выражение // и тестируют работу программы. public class Lambda { public static void main(String[] args) { // 1. Реализация для массивов типа Double // 1.1. Объявить ссылку на интерфейс ISumArrays<T> ISumArrays<Double> ref; // 1.2. Сформировать лямбда-выражение с привязкой к типу Double ref = (array1, array2) -> { try { // Проверка на нулевую длину массивов if (array1.length==0) throw new EmptyArrayException("array1 is empty."); if (array2.length==0) throw new EmptyArrayException("array2 is empty."); // Проверка на равенство элементов в массивах if (array1.length!=array2.length) throw new ArrayIndexOutOfBoundsException("Arrays are not equal"); } catch (EmptyArrayException e) { System.out.println(e.getMessage()); return null; } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); return null; } // Код суммирования массивов Double[] array3 = new Double[array1.length]; for (int i=0; i<array1.length; i++) array3[i] = array1[i] + array2[i]; return array3; }; // 1.3. Объявить два массива различной длины Double[] AD1 = { 2.0, 1.5, 3.8 }; Double[] AD2 = { 1.1, 4.0 }; // 1.4. Вызвать метод AddMethod() из класса ArrayMethod<T> Double[] AD3; ArrayMethod<Double> obj = new ArrayMethod<Double>(); AD3 = obj.AddMethod(AD1, AD2, ref); // 1.5. Вывести массив AD3 if (AD3 != null) { System.out.println("Array AD3:"); for (int i=0; i<AD3.length; i++) System.out.print(" " + AD3[i]); System.out.println(); } // 2. Реализация для одинаковых массивов // 2.1. Объявить одинаковые массивы Double[] AD4 = { 1.5, 2.5, 3.3 }; Double[] AD5 = { 2.0, 1.8, 1.9 }; // 2.2. Вызвать метод суммирования массивов AD3 = obj.AddMethod(AD4, AD5, ref); // 2.3. Вывести массив AD3 if (AD3 != null) { System.out.println("Array AD3:"); for (int i=0; i<AD3.length; i++) System.out.print(" " + AD3[i]); System.out.println(); } } }
Результат работы программы
Arrays are not equal Array AD3: 3.5 4.3 5.199999999999999
⇑
3. Пример генерирования исключения, которое обрабатывается специально разработанным классом
Условие задачи. Разработать класс NegativeRootException, который обрабатывает исключение возникающее при попытке взятия корня квадратного из отрицательного числа. Реализовать лямбда-выражение, которое вычисляет площадь треугольника по длинам его сторон. Расчет ведется по формуле Герона. Если в формуле Герона возникает корень из отрицательного числа (треугольник не существует), то сгенерировать исключение NegativeRootException. Исключение должно генерироваться в лямбда-выражении.
Розв’язок. Текст решения задачи следующий.
// Генерирование исключений в лямбда-выражениях // Объявить функциональный интерфейс interface INegativeRoot { // Объявить метод, определяющий площадь треугольника по его сторонам double AreaTriangle(double a, double b, double c); } // Создать класс исключения, который обрабатывает корень квадратный из отрицательного числа // Такое исключение есть контролированным (checked). class NegativeRootException extends Exception { // Конструктор класса NegativeRootException(String message) { super(message); // вызвать конструктор суперкласса Exception } } // Класс, содержащий методы, которые реализуют лямбда-выражение и // тестируют работу программы. public class Lambda { @SuppressWarnings("finally") public static void main(String[] args) { // 1. Объявить ссылку на INegativeRoot INegativeRoot ref = null; // 2. Реализовать лямбда-выражение, вычисляющее площадь // треугольника по формуле Герона ref = (a, b, c) -> { double p = (a+b+c)/2; // полупериметер double t = p*(p-a)*(p-b)*(p-c); // подкорневое выражение try { // проверка на отрицательный корень с генерированием исключения if (t<0) { t=0; throw new NegativeRootException("Exception: negative root."); } return Math.sqrt(t); } catch (NegativeRootException e) { t = 0; System.out.println(e.getMessage()); } finally { // Блок, который выполняется всегда return t; } }; // 3. Протестировать лямбда-выражение на исключительную ситуацию double res = ref.AreaTriangle(1, 1, 5); // Exception: negative root. // 4. Вывести результат System.out.println("res = " + res); // res = 0.0 } }
После выполнения программа выдаст следующий результат
Exception: negative root. res = 0.0
⇑
Связанные темы
- Лямбда-выражения. Основные понятия. Функциональный интерфейс. Примеры
- Лямбда-выражения для обобщенных функциональных интерфейсов
- Передача лямбда-выражения в метод в качестве параметра. Примеры
- Доступ к элементам класса в лямбда-выражениях. Захват переменных в лямбда-выражениях. Примеры
⇑