[Из песочницы] Новый класс Optional в Java 8, не панацея от NullPointerException

В релизе Java 8 появился новый класс Optional призванный помочь разработчикам в обработке NullPointerException.С NullPointerException встречались многие и во многих случаях, это очень неприятное исключение заставляет дебажить код, дабы понять, в каком месте, кто-то из твоих предшественников (а возможно и ты), не поставили пресловутую проверку на null.

А что если вообще запретить назначать тем или иным полям класса значения равные null? Java естественно не запрещает нам делать этого, но с Optional это становится немного удобнее и нагляднее.

Итак, приступим к описанию основных возможностей этого нововведения.

Создание объектов OptionalДля начала приведу пример класса с использованием Optional: import java.util.Date; import java.util.Optional;

public class Person {

private Optional firstName; private Optional secondName; private Optional age; private Optional address; public Optional getFirstName () { return firstName; }

public void setFirstName (String firstName) { this.firstName = Optional.ofNullable (firstName); }

public Optional getSecondName () { return secondName; }

public void setSecondName (String secondName) { this.secondName = Optional.of (secondName); }

public Optional getAge () { return age; }

public void setAge (int age) { this.age = Optional.ofNullable (age); } public Optional getAddress () { return address; }

public void setAddress (PersonAddress address) { this.address = Optional.of (address); } } Как видите при установке полям класса значений, через «set» методы, мы используем статические методы класса Optional — of (), ofNullable ()).Эти методы используются для создания объектов типа Optional, ниже приведены примеры такого создания объектов:

/** Создание Optional объектов */ //Пустой Optional объект Optional optionalPerson = Optional.empty (); //Optional объект с ненулевым значением Optional optionalNonNull = Optional.of (new Person ()); //Optional объект с возможностью нулевого значения Optional optionalNullable = Optional.ofNullable (new Person ()); Использование Optional для устранения избыточного кода Часто проверка на null объектов, которые передаются или обрабатываются в различных методах, занимает множество строчек кода, если необходимо работать не только с переданным объектом, а с полем объекта, которое в свою очередь содержит еще одно поле, к примеру текстового описания.При попытке обратиться напрямую к этому полю через цепочку объектов и при условии, что переданный объект по каким-то причинам пришел равный null мы получим NullPointerException, поэтому для начала нам необходимо проверить каждый объект на null и уже потом взять необходимое нам текстовое поле:

Person person = getDefaultPerson (); if (person!= null) { PersonAddress personAddress = person.getAddress (); if (personAddress!= null) { PersonAddressStreet street = personAddress.getStreet (); if (street!= null) { streetName = street.getStreetName (); } else { streetName = «EMPTY»; } } } А теперь все то же самое, но с использованием Optional: String streetName = person.flatMap (Person: getAddress) .flatMap (PersonAddress: getStreet) .map (PersonAddressStreet: getStreetName) .orElse («EMPTY»); Намного лаконичнее, не правда ли? Действия с объектом, с использованием метода ifPresent () Метод ifPresent () позволяет также устранить некоторую избыточность кода, следующего вида: if (person!= null) { System.out.println (person); } Те же действия, но с использованием Optional: person.ifPresent (System.out: println); Действия с объектом с использованием isPresent () isPresent () не дает нам большой выгоды по устранению избыточности кода, но зато придает немного большую информативность написанному коду.Как было раньше:

if (person!= null) { System.out.println (person) } else { System.out.println («Person not found!»); } То же самое, но с использованием Optional: if (person.isPresent ()) { System.out.println (person.get ()); } else { System.out.println («Person not found!»); } Действия с объектом с использованием orElse (), orElseThrow () И напоследок еще несколько методов для наведения «красоты» в коде.Как было раньше:

Person personNew = person!= null? person: new Person (); То же самое, но с использованием Optional: Person personNew = person.orElse (new Person ()); Или, если не хотим создавать объект, можно выбросить исключение: Person personNewThrow = person.orElseThrow (Exception: new); Заключение Естественно Optional не дает никакой гарантии избавления от NullPointerException и все проверки на null можно было описывать и раньше, но с Optional это действия становятся быстрее и проще, так как дополнительные методы для проверки объекта или проверки и каких-то дальнейших действий с объектом уже описаны и нам осталось только воспользоваться ими в своем коде.А также несомненно, Optional помогает придать большую информативность коду, повысить его читабельность.

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

Информация для дальнейшего изучения:

© Habrahabr.ru