Java. Генерирование исключений в лямбда-выражениях. Примеры

Генерирование исключений в лямбда-выражениях. Примеры


Содержание


Поиск на других ресурсах:




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

 


Связанные темы