هر شیء Optional مانند یک ظرف است که یک شیء دیگر – که میتواند null باشد- در دل خود نگه میدارد. کتابخانههای جدید (بعد از جاوا 8) مقدار خروجی برخی متدهایی که ممکن است null برگردانند را از نوع Optional تعیین میکنند.
مثلاً فرض کنید متد findPerson به شکل زير تعريف شده باشد:
public Person findPerson(String ssn) {...}
به این ترتیب، اگر متد findPerson به شکل زير استفاده شود، ممکن است منجر به NullPointerException شود (چون شاید findPerson مقدار null برگرداند) :
System.out.println( findPerson ("65232").getAddress() );
یک کتابخانه جدید، احتمالاً findPerson را به شکل زير تعريف میکند که به جای Person مقداری از نوع Optional<Person> برمیگرداند:
public Optional<Person> findPerson(String ssn) {...}
وقتی یک متد مقدار Optional برمیگرداند، یعنی کاربر این متد باید مواظب باشد چون خروجی این متد «ممکن است شامل null باشد». به عبارت دیگر نویسنده متد، با این کار تصريح میکند که شاید این متد خروجی نداشته باشد و استفادهکنندگان باید قبل از کاربرد آن، چک کنند که خروجی آن null نباشد. مثلاً از طريق متد isPresent :
findPerson("65232").ifPresent(person->System.out.println(person.getAddress()));
یا حتی بهتر (اگر با امکانات جاوا 8 آشنا هستید) :
findPerson("65232")
.map(Person::getAddress)
.ifPresent(System.out::println);
البته این امکان جدید (Optional) معجزه نمیکند! همچنان ممکن است NullPointerException به وجود آید. استفادهکنندگان Optional هم ممکن است از آن بهرهبرداری اشتباه کنند. مثلاً بدون این که چک کنند که درون یک Optional مقدار null هست یا خیر، از آن استفاده کنند (با کمک متد get که شیء داخلی آن را برمیگرداند) و بنویسند:
System.out.println( findPerson("65232").get().getAddress() );
ولی به هر حال Optional کمک میکند که برنامهنویس حواسش را جمع کند. اشتباه کمتر میشود و NullPointerException هم کمتر رخ میدهد. کدهای تولیدشده هم تمیزتر و خواناتر و موجزتر میشوند.