JavaRush /จาวาบล็อก /Random-TH /คอฟฟี่เบรค #161. วิธีจัดการ Null ใน Java โดยใช้ตัวเลือก

คอฟฟี่เบรค #161. วิธีจัดการ Null ใน Java โดยใช้ตัวเลือก

เผยแพร่ในกลุ่ม
ที่มา: สื่อ บทความนี้จะช่วยให้คุณเข้าใจวัตถุประสงค์ของ Optional ได้ดียิ่งขึ้นเมื่อทำงานกับโค้ด Java คอฟฟี่เบรค #161.  วิธีจัดการ Null ใน Java โดยใช้ตัวเลือก - 1เมื่อฉันเริ่มทำงานกับโค้ด Java ครั้งแรก ฉันมักจะได้รับคำแนะนำให้ใช้ตัวเลือกเสริม แต่ในเวลานั้น ฉันไม่ค่อยเข้าใจว่าทำไมการใช้ Optional จึงดีกว่าการใช้การจัดการกับค่าว่าง ในบทความนี้ ฉันต้องการแบ่งปันกับคุณว่าทำไมฉันถึงคิดว่าเราทุกคนควรใช้ Optional มากกว่านี้ และวิธีหลีกเลี่ยงการใส่โค้ดที่เป็นทางเลือกมากเกินไป ซึ่งเป็นอันตรายต่อคุณภาพของโค้ด

ทางเลือกคืออะไร?

พารามิเตอร์ทางเลือกใช้ในการพกพาออบเจ็กต์และเปิดใช้งานการอ้างอิง nullที่จะจัดการโดย API ต่างๆ ลองดูข้อมูลโค้ด:
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
เรามี ตัวอย่าง กาแฟที่เราได้รับน้ำตาลจากอินสแตนซ์ของวัตถุน้ำตาล หากเราถือว่าค่าปริมาณไม่เคยถูกตั้งค่าในตัว สร้าง Coffeeดังนั้นcoffee.getSugar().getQuantity()จะส่งคืนค่าNullPointerException แน่นอนว่าเราสามารถใช้ การตรวจสอบ ค่าว่างแบบ เก่าที่ดี เพื่อแก้ไขปัญหาได้ เสมอ
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
ตอนนี้ทุกอย่างดูเหมือนจะดี แต่เมื่อเขียนโค้ด Java เราควรหลีกเลี่ยงการใช้ การตรวจ สอบค่าว่าง เรามาดูกันว่าสามารถทำได้โดยใช้ตัวเลือกเสริม

วิธีการสร้างทางเลือก

มีสามวิธีในการสร้างออบเจ็กต์เสริม:
  • ของ (ค่า T) - การสร้างอินสแตนซ์ของวัตถุเสริมที่ไม่ใช่ค่าว่าง โปรดทราบว่าการใช้()เพื่ออ้างถึงวัตถุnullจะทำให้เกิดNullPointerException

  • ofNullable(ค่า T) - สร้างค่าเสริมสำหรับวัตถุที่สามารถเป็นค่าว่างได้

  • ว่างเปล่า() - สร้างอินสแตน ซ์ทางเลือกที่แสดงถึงการอ้างอิงถึงnull

// пример использования Optional.of(T Value)
String name = "foo";
Optional<String> stringExample = Optional.of(name)
// пример использования Optional.ofNullable(T Value)
Integer age = null;
Optional<Integer> integerExample= Optional.ofNullable(age)
// пример использования Optional.empty()
Optional<Object> emptyExample = Optional.empty();
ดังนั้นคุณจึงมีวัตถุเสริม ตอนนี้เรามาดูสองวิธีหลักสำหรับตัวเลือกเสริม:
  • isPresent() - เมธอดนี้จะบอกคุณว่าออบเจ็กต์เสริมมีค่าที่ไม่ใช่ค่าว่างหรือไม่

  • get() - รับค่าของ Optional ด้วยค่าปัจจุบัน โปรดทราบว่าการเรียกget()บนตัวเลือกว่างจะส่งผลให้เกิดNullPointerException

โปรดทราบว่าหากคุณใช้เฉพาะget()และisPresent()เมื่อทำงานกับ Optional คุณจะพลาด! เพื่อให้เข้าใจสิ่งนี้ เรามาเขียนตัวอย่างข้างต้นใหม่โดยใช้ตัวเลือกเสริม

การปรับปรุงการตรวจสอบ Null ด้วยตัวเลือก

แล้วเราจะปรับปรุงโค้ดข้างต้นได้อย่างไร? ด้วย Optional เราสามารถเข้าใจการมีอยู่ของวัตถุโดยใช้isPresent()และดึงข้อมูลโดยใช้get( ) เริ่มต้นด้วยการ บรรจุผลลัพธ์ของcoffee.getSugar()ด้วย Optional และใช้ เมธอด isPresent() สิ่งนี้จะช่วยเราพิจารณาว่าgetSugar() ส่งคืน ค่าว่างหรือไม่
Coffee coffee = new Coffee();
Optional<String> sugar = Optional.ofNullable(coffee.getSugar());
int quantity = 0;
if (sugar.isPresent()) {
  Sugar sugar = sugar.get();
  int quantity = sugar.getQuantity();
}
จากตัวอย่างนี้ การบรรจุผลลัพธ์ของcoffee.getSugar()ลงใน Optional ดูเหมือนจะไม่เพิ่มมูลค่าใดๆ แต่เพิ่มความยุ่งยาก เราสามารถปรับปรุงผลลัพธ์ได้โดยใช้สิ่งที่ฉันคิดว่าเป็นฟังก์ชันโปรดของฉันจากคลาสเสริม:
  • map(Function<? super T,? extensions U> mapper) - จับคู่ค่าที่มีอยู่ใน Optional กับฟังก์ชันที่ให้มา หากพารามิเตอร์ Optional ว่างเปล่า ดังนั้นmap()จะส่งกลับOptional.empty( )

  • orElse ( T other)เป็นเวอร์ชัน "พิเศษ" ของ เมธอด get() สามารถรับค่าที่อยู่ในตัวเลือกได้ อย่างไรก็ตาม ในกรณีของ Optional ที่ว่าง เปล่าระบบจะส่งคืนค่าที่ส่งไปยัง เมธอด orElse()

วิธีการจะส่งกลับค่าที่มีอยู่ในอินสแตนซ์ทางเลือก แต่ถ้าพารามิเตอร์ Optional ว่างเปล่า หมายความว่าไม่มีค่า ดังนั้นorElse()จะส่งคืนค่าที่ส่งไปยังลายเซ็นเมธอด ซึ่งเรียกว่าค่าเริ่มต้น
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
มันเจ๋งจริงๆ - อย่างน้อยฉันก็คิดอย่างนั้น ตอนนี้ หากในกรณีของค่าว่าง เราไม่ต้องการส่งคืนค่าเริ่มต้น เราจำเป็นต้องส่งข้อยกเว้นบางประเภท orElseThrow(Supplier<? ขยาย X> ข้อยกเว้นซัพพลายเออร์)ส่งคืนค่าที่มีอยู่ในพารามิเตอร์ทางเลือก หรือส่งข้อยกเว้นหากตัวเลือกว่างเปล่า
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
อย่างที่คุณเห็น ตัวเลือกเสริม มีข้อดีหลายประการ:
  • บทคัดย่อ การตรวจสอบ โมฆะ
  • จัดเตรียม API สำหรับการจัดการ วัตถุ ว่าง
  • อนุญาตให้มีแนวทางการประกาศเพื่อแสดงสิ่งที่กำลังประสบความสำเร็จ

วิธีที่จะมีประสิทธิภาพด้วยตัวเลือก

ในงานของฉัน ฉันใช้ Optional เป็นประเภทการส่งคืนเมื่อเมธอดสามารถส่งคืนสถานะ "ไม่มีผลลัพธ์" ฉันมักจะใช้มันเมื่อกำหนดประเภทการส่งคืนสำหรับวิธีการ
Optional<Coffee> findByName(String name) {
   ...
}
บางครั้งก็ไม่จำเป็น ตัวอย่างเช่น หากฉันมีเมธอดที่ส่งคืนintเช่นgetQuantity()ใน คลาส Sugarเมธอดนั้นอาจส่งคืน0หากผลลัพธ์เป็นnullเพื่อแสดงถึง "no quantity" เมื่อรู้สิ่งนี้แล้ว เราก็คิดได้ว่า พารามิเตอร์ Sugarใน คลาส Coffeeสามารถแสดงเป็นตัวเลือกได้ เมื่อมองแวบแรก ดูเหมือนว่าจะเป็นความคิดที่ดี เนื่องจากตามทฤษฎีแล้ว น้ำตาลไม่จำเป็นต้องมีอยู่ในกาแฟ อย่างไรก็ตาม นี่คือจุดที่ฉันต้องการกล่าวถึงเมื่อไม่ใช้ตัวเลือก เราควรหลีกเลี่ยงการใช้ตัวเลือกเสริมในสถานการณ์ต่อไปนี้:
  • เป็นประเภทพารามิเตอร์สำหรับPOJOเช่นDTO ตัวเลือกต่างๆ ไม่สามารถทำให้เป็นซีเรียลไลซ์ได้ ดังนั้นการใช้ตัวเลือกเหล่านั้นใน POJO จะทำให้อ็อบเจ็กต์ไม่สามารถซีเรียลไลซ์ได้

  • เป็นอาร์กิวเมนต์วิธีการ หากอาร์กิวเมนต์ของเมธอดสามารถเป็นnull ได้ ดังนั้นจากมุมมองของโค้ดล้วนๆ การส่งค่าnullยังคงดีกว่าการส่งผ่าน Optional นอกจากนี้ คุณสามารถสร้างวิธีการโอเวอร์โหลดเพื่อจัดการกับการไม่มีอาร์กิวเมนต์วิธีการ null ในทางนามธรรมได้

  • เพื่อแสดงถึงวัตถุคอลเลกชันที่หายไป คอลเลกชั่นสามารถว่างเปล่าได้ ดังนั้นคอลเลกชั่น ว่าง เช่นSetหรือList ที่ว่างเปล่า จะต้องถูกใช้เพื่อแสดงคอลเลกชั่นที่ไม่มีค่า

บทสรุป

ตัวเลือกเสริมได้กลายเป็นส่วนเสริมที่ทรงพลังสำหรับไลบรารี Java มีวิธีการจัดการวัตถุที่อาจไม่มีอยู่ ดังนั้นจึงควรนำมาพิจารณาเมื่อพัฒนาวิธีการโดยไม่ตกหลุมพรางของการละเมิด ใช่ คุณสามารถเขียนโค้ดที่ยอดเยี่ยมที่ใช้การตรวจสอบค่าว่างและการจัดการค่าว่างได้ แต่ชุมชน Java ต้องการใช้ทางเลือก โดยจะสื่อสารวิธีจัดการกับค่าที่หายไปอย่างมีประสิทธิภาพ อ่านได้ง่ายกว่าการตรวจสอบ Null ที่ยุ่งวุ่นวาย และส่งผลให้โค้ดของคุณมีจุดบกพร่องน้อยลงในระยะยาว
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION