menusearch
javapro.ir

کلاس Optional در زبان برنامه نویسی جاوا چیست و چرا باید از آن استفاده کنیم؟

جستجو
پنج شنبه ۲۲ آذر ۱۴۰۳ | ۲۳:۵۱:۲۵
۱۴۰۲/۱۲/۱۲ شنبه
(3)
(0)
کلاس Optional در زبان برنامه نویسی جاوا چیست و چرا باید از آن استفاده کنیم؟
کلاس Optional در زبان برنامه نویسی جاوا چیست و چرا باید از آن استفاده کنیم؟

استثناء اشاره گر به تهی (NullPointerException)

 

این استثناء زمانی رخ میدهد که به متغیری دسترسی پیدا میکنیم که به هیچ آبجکتی اشاره نمیکند. مثلا :

 

   String javaPro=null;

   if(javaPro.equals("Best")){

        System.out.println(true);

}

 

به دلیل اینکه String تعریف شده به هیچ ابجکتی اشاره نمیکند(اصطلاحا new نشده) استثنای nullpointerException روی میدهد.

این استثنا زیر کلاسی از RuntimeException است بنابراین از نوع unchecked exception (استثنای چک نشده) است.

 

راه حل : استفاده از کلاس Optional

کلاسی است که در جاوا ۸ معرفی شده و هدف ان جلوگیری از استثناء معروف nullpointerexception است(هرچند گویا به طور کامل از چنین خطایی نتوانسته جلوگیری کند)

میتوان گفت بیشتر ابزاری است برای راحت تر چک کردن مقادیر تهی و راحت تر گریختن از خطای nullpointerexception

بیگمان هرکس که با جاوا کد زده باشد با خطای nullpointerexception اشنا است.

 

فرض کنید کلاسی به نام Person داریم و در ان یک فیلد به نام name و یک Getter برای آن داریم:

کد

public class Person {

 

private String name;

public String getName() {

      return name;

   }

}

 

 

حال در کلاس main برنامه ی خود یک متد داریم به این صورت:(فرض کنید این متد بر اساس یکسری عملیات به مقدار null رسیده است..مثلا Person را از دیتابیس خوانده و هیچ مقداری پیدا نکرده است

کد

}()public static Person getPerson

    return null;

}

طبعا هنگامی که در main چنین خط کدی را بنویسیم :

 

public static void main(String[] args) {

      getPerson().getName();

   }

 

به خطای nullpointerexception برمیخوریم.

حال راه حل جاوا هشت برای گریز از این خطا چیست؟

ابتدا توضیحاتی اندک ولی کارامد درمورد متد های کلاس Optional میدهیم:

 

متد های استاتیک کلاس Optional

کلاس اپشنال از دیزاین پترن Factory استفاده میکند(اجازه ی ساخت شی با کلیدواژه new از ان را نداریم)

 

Optional.empty();
Optional.of(T t);
Optional.ofNullable(T value);

متد اول به جای همان مثال بالا که null برگشت دادیم استفاده میشود.

متد دوم یک مقدار میپذیرد با این شرط که تهی نباشد و متد سوم میتواند مقداری تهی نیز بپذیرد.(در صورتی که مقدار تهی باشد یک Optional.empty برمیگرداند )

حال مثال اول را اینگونه بازنویسی میکنیم:

در اغاز بایستی نوع بازگشتی متد را از جنس Optionalتعریف کنیم:

 

  public static Optional<Person> getPerson() {
return Optional.empty();
}

 

نکته : در کد بالا شرایط قبلی برقرار است. یعنی مثلا در پایگاه داده، داده ی مورد نظر پیدا نشده و ما به جای null از کلاس Optional بعنوان نوع برگشتی استفاده میکنیم.

 

حال در متد main متد getPerson را call میکنیم:

 

  public static void main(String[] args) {
Optional<Person> op=getPerson();
System.out.println(op);
}

 

خواهیم دید که دیگر خبری از ارور nullpointerexception نیست بلکه چنین چیزی در خروجی مشاهده میکنیم:

 

Optional.empty    

 

 

سایر متد های سودمند کلاس Optional

 

 

   orElse(T t);

 

 

اگر مقدار وجود داشت...مقدار Tرا برگشت میدهد وگرنه مقداری که در ورودی متد داده اید را برگشت میدهد(دیگر مقدار null درکار نخواهد بود)

مثال :

public class Main {
    public static void main(String[] args) {
    Student student = Optional.ofNullable(getStudentWithName("hamza")).orElse(new Student("no one", 0, "Unknown"));
    System.out.println(student.getName());
    }

    public static Student getStudentWithName(String name ){
        // lets suppose that our database contain only 2 students ahmed and hamza .
        if (name.equals("hamza") || name.equals("ahmed")) {
           return new Student(name, 22, "Morocco");
        } else {
              return null ;
        }
    }

}

 

ممکن است اگر مقداری وجود نداشت بخواهید استثنایی به راه بیاندازید :

 

 

orElseThrow(T t)

 

 

متدی است که برای ایجاد یک استثنا در صورت خالی بودن Optional کاربرد دارد. برخلاف orElse که یک مقدار پیش‌فرض را برمی‌گرداند، orElseThrow به شما اجازه می‌دهد یک استثناء ایجاد کنید.

مثال :

public class Main {
   public static void main(String[] args) throws StudentNotFoundException {
      Student student = Optional.ofNullable(getStudentWithName("fs")).orElseThrow(()-> new StudentNotFoundException("the Student is not Present "));
      System.out.println(student.getName());
    }

    public static Student getStudentWithName(String name ){
        // lets suppose that our database contain only 2 students ahmed and hamza .
        if (name.equals("hamza") || name.equals("ahmed")) {
            return new Student(name, 22, "Morocco");
        } else {
            return null ;
        }
    }

}

 

متد دیگری که بسیار مهم است ( زمانی که بخواهیم قبل از دریافت مقدار درون Optional چک کنیم که دقیقا میداری دارد یا خیر)

 

 

   isPresent();

 

 

گر مقداری داخل اپشنال بود true برگشت میدهد اگر نبود false

 

 

get();

 

 

 

اگر مقدار وجود داشت برگشت میدهد و اگر نبود nosuchelementexception برگشت میدهد(و بازهم خبری از ارور null نیست)

 

ifPresent(Consumer<? super T> consumer)

 

 

اگر مقدار وجود داشت عملیات مورد نظرمان انجام شود

 

ifPresentOrElse(Consumer<? super T> consumer,Runnable run)

 

 

اگر مقدار وجود داشت عملیات مورد نظر انجام شود و اگر تهی بود متد run از اینترفیس Runnable صدا زده میشود

و بسیار متد های سودمند دیگر
توجه داشته باشید Runnable در بالا ربطی به ترد ندارد و صرفا بخاطر متد run از ان استفاده شده است

 

 

چه زمانی از Optional استفاده نکنیم؟

  • بعنوان نوع خروجی Getter های یک POJO از Optional استفاده نکنید (بنابراین در DTO، Entity و.. استفاده از Optional توصیه نمیشود)
  • در کلاس هایی که Serializable هستند استفاده نکنید .به این دلیل که داده ای ناخواسته نمایش داده خواهد شد.

 

مثال :

private String firstName;

public Optional<String> getFirstName() {

    return Optional.ofNullable(firstName);

}

   public void setFirstName(String firstName) {

      this.firstName = firstName;

   }

 

در چنین شرایطی اگر خروجی جیسون داشته باشید مشاهده خواهید کرد:

{"firstName":{"present":true}}

درحالی که باید مثلا چنین خروجی مشاهده میکردید:

{"firstName":"JavaPro"}

 

یکی از کاربرد های خیلی خوب کلاس Optional در Spring data jpa است. زمانی که یک Repository دارید میتوانید بعنوان Return type از کلاس Optional استفاده کنید(مزیت های خیلی زیادی دارد). مثال :

 

package com.javapro;

import org.springframework.lang.Nullable;

 

@Repository

interface UserRepository extends JpaRepository<User, Long> {

 

   User getByEmailAddress(EmailAddress emailAddress);

 

   Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); // Best approach

}

 

 

با تشکر از خانم ساناز اردشیری جهت تایپ نمودن محتوا.

منابع:

Oracle.com

baeldung.com

javaland

docs.spring.io

geeksforgeeks

 

متد های کلاس Optional
متد های کلاس Optional
نظرات کاربران
*نام و نام خانوادگی
* پست الکترونیک
* متن پیام

بستن
*نام و نام خانوادگی
* پست الکترونیک
* متن پیام

1 نظر
F esteki
جمعه هجدهم اسفند ۰۲
پاسخ
()
()
F esteki
ممنون از متن کامل و توضيحات بسيار خوبتون با مثالهايي که موضوع را کاملا قابل فهم کرد
هدر سایت
مشاهده سرفصل ها و ثبت نام در دوره Spring Boot جاواپرو  [کلیک کنید]
آموزش پروژه محور اسپرینگ بوت(Spring Boot)-سیستم دانشگاه
ثبت نام در دوره آموزش Spring security
دوره معماری میکروسرویس ها (Microservices) با استفاده از Spring Boot و Spring Cloud
دوره پرتاب | آموزش پیش نیازهای برنامه نویسی
دوره آموزش مبانی زبان برنامه نویسی جاوا
دوره آموزش مفاهیم پیشرفته زبان برنامه نویسی جاوا
مقدمه ای از زبان برنامه نویسی جاوا(java)
آموزش زبان برنامه نویسی جاوا
آموزش گرافیک در زبان برنامه نویسی جاوا
آموزش مدیریت چیدمان گرافیکی در زبان جاوا
آموزش ساخت بازی دوبعدی در زبان جاوا
Collection ها در زبان برنامه نویسی جاوا
آموزش پروژه محور ساخت برنامه مدیریت بانک با JavaFX
نمونه پروژه های رایگان زبان جاوا
آموزش دیتابیس در زبان برنامه نویسی جاوا
نمونه مثال پایه ای زبان برنامه نویسی جاوا
نمونه مثال String در زبان برنامه نویسی جاوا
آموزش جامع برنامه نویسی JavaFX
آموزش ساخت برنامه آزمون تستی در JavaFX
آموزش برنامه نویسی سوکت در جاوا
آموزش ساخت برنامه دفترچه تلفن با JavaFX
آموزش ساخت ربات ساده تلگرام با زبان جاوا
آموزش ساخت برنامه ماشین حساب با JavaFX
آموزش ساخت برنامه ساده مدیریت ایمیل ها با JavaFX
دوره آموزش Spring Boot
سفارش انجام پروژه زبان برنامه نویسی جاوا(JAVA)
سفارش انجام پروژه برنامه نویسی متلب(MATLAB) با قیمت منصفانه و تحویل به موقع
سفارش انجام پروژه زبان برنامه نویسی سی شارپ (#C)
سفارش انجام پروژه زبان برنامه نویسی سی(C)
سفارش انجام پروژه زبان برنامه نویسی پایتون(Python)
سفارش انجام پروژه زبان برنامه نویسی PHP (پی اچ پی)
سفارش انجام پروژه زبان برنامه نویسی اسمبلی(Assembly)
سفارش انجام پروژه زبان برنامه نویسی جاوا اسکریپت (Javascript)
سفارش انجام پروژه هوش مصنوعی
سفارش انجام پروژه طراحی الگوریتم
سفارش انجام پروژه ساختمان داده ها
سفارش انجام پروژه مهندسی نرم افزار
سفارش انجام پروژه شبکه های کامپیوتری
سفارش انجام پروژه پایگاه داده: دیتابیس (database)
 سفارش انجام پروژه سیستم عامل
سفارش انجام پروژه پاورپوینت(PowerPoint)
سفارش انجام پروژه اکسل (Excel)
سفارش انجام تحقیق و تهیه مقاله
سوالات متداول برنامه نویسی
جدیدترین مطالب
گفتگو را شروع کنید
مشاوره ،تدریس خصوصی و سفارش انجام انواع پروژه های برنامه نویسی