วิธีที่ดีที่สุดในการจัดการ nulls ใน Java? [ปิด]


21

ฉันมีรหัสที่ล้มเหลวเพราะ NullPointerException มีการเรียกวิธีการบนวัตถุที่วัตถุนั้นไม่มีอยู่

อย่างไรก็ตามสิ่งนี้ทำให้ฉันคิดถึงวิธีที่ดีที่สุดในการแก้ไขปัญหานี้ ฉันควรจะป้องกันโค้ดสำหรับ nulls เสมอหรือไม่เพื่อที่ฉันจะได้รหัสในอนาคตสำหรับข้อยกเว้นตัวชี้ null หรือฉันควรแก้ไขสาเหตุของ null เพื่อไม่ให้เกิด downstream

คุณคิดยังไง?


5
ทำไมคุณไม่ "แก้ไขสาเหตุของการโมฆะ"? คุณช่วยยกตัวอย่างว่าทำไมตัวเลือกนี้ถึงไม่ใช่ตัวเลือกที่สมเหตุสมผลเท่านั้น? เห็นได้ชัดว่ามีบางสิ่งที่จะผลักคุณออกไปจากที่เห็นได้ชัด มันคืออะไร? ทำไมการไม่แก้ไขรากทำให้ตัวเลือกแรกของคุณ
S.Lott

การแก้ไข "สาเหตุที่แท้จริง" ของปัญหาอาจช่วยในระยะสั้น แต่ถ้ารหัสยังคงไม่ตรวจสอบการตรวจหาโมฆะอย่างถูกต้องและนำกลับมาใช้โดยกระบวนการอื่นที่อาจแนะนำโมฆะฉันจะต้องแก้ไขอีกครั้ง
Shaun F

2
@Shaun F: หากรหัสถูกทำลายก็จะเสีย ฉันไม่เข้าใจวิธีที่เป็นไปได้ที่โค้ดจะสร้างโมฆะที่ไม่คาดคิดและไม่ได้รับการแก้ไข เห็นได้ชัดว่ามีบางสิ่งที่ "จัดการโง่" หรือ "การเมือง" เกิดขึ้น หรือบางสิ่งบางอย่างที่อนุญาตให้รหัสที่ผิดพลาดเป็นที่ยอมรับได้ คุณช่วยอธิบายว่ารหัสที่ผิดพลาดไม่ได้รับการแก้ไขได้อย่างไร ภูมิหลังทางการเมืองที่ทำให้คุณถามคำถามนี้คืออะไร
S.Lott

1
"มีความเสี่ยงต่อการสร้างข้อมูลในภายหลังที่มีค่าเป็นศูนย์" หมายความว่าอย่างไร หาก "ฉันสามารถแก้ไขรูทีนการสร้างข้อมูล" แสดงว่าไม่มีช่องโหว่เพิ่มเติม ฉันไม่สามารถเข้าใจว่า "การสร้างข้อมูลในภายหลังซึ่งมีค่าเป็นศูนย์" หมายความว่าอย่างไร ซอฟต์แวร์ Buggy?
S.Lott

1
@ S.Lott การห่อหุ้มและความรับผิดชอบเดี่ยว รหัสทั้งหมดของคุณไม่ "รู้" รหัสอื่นของคุณทำอะไร หากชั้นเรียนยอมรับ Froobinators มันจะทำให้มีข้อสมมติฐานน้อยที่สุดเท่าที่จะเป็นไปได้เกี่ยวกับผู้สร้าง Froobinator และวิธีการ มันทำมาจากรหัส "ภายนอก" หรือมาจากส่วนอื่นของฐานรหัส ฉันไม่ได้บอกว่าคุณไม่ควรแก้ไขโค้ดบั๊กกี้ แต่ค้นหา "โปรแกรมป้องกัน" และคุณจะพบว่า OP หมายถึงอะไร
Paul Draper

คำตอบ:


45

หาก null เป็นพารามิเตอร์อินพุตที่สมเหตุสมผลสำหรับวิธีการของคุณให้แก้ไขเมธอด ถ้าไม่แก้ไขผู้โทร "สมเหตุสมผล" เป็นคำที่ยืดหยุ่นดังนั้นฉันขอเสนอการทดสอบต่อไปนี้: วิธีการที่ควรใช้อินพุตว่าง? หากคุณพบคำตอบที่เป็นไปได้มากกว่าหนึ่งคำตอบค่า Null ไม่ใช่คำตอบที่สมเหตุสมผล


1
มันง่ายอย่างที่คิด
biziclop

3
Precondition.checkNotNull(...)ฝรั่งมีวิธีการช่วยเหลือบางอย่างที่ดีมากทำให้การตรวจสอบเป็นโมฆะเป็นง่ายๆเป็น ดูstackoverflow.com/questions/3022319/…

กฎของฉันคือการเริ่มต้นทุกอย่างให้เป็นค่าเริ่มต้นหากเป็นไปได้และกังวลเกี่ยวกับข้อยกเว้นที่เป็นโมฆะในภายหลัง
davidk01

Thorbjørn: ดังนั้นมันจะแทนที่ NullPointerException โดยไม่ได้ตั้งใจด้วย NullPointerException โดยเจตนาหรือไม่? ในบางกรณีการทำการตรวจสอบเบื้องต้นอาจมีประโยชน์หรือจำเป็น แต่ฉันกลัวการตรวจสอบที่ไม่มีสติในสำเร็จรูปที่เพิ่มมูลค่าเล็กน้อยและทำให้โปรแกรมใหญ่ขึ้น
281377

6
ถ้า null ไม่ใช่พารามิเตอร์อินพุตที่สมเหตุสมผลให้กับเมธอดของคุณ แต่การเรียกใช้เมธอดมีแนวโน้มที่จะผ่านค่า null โดยไม่ตั้งใจ (โดยเฉพาะถ้าเมธอดเป็นแบบสาธารณะ) คุณอาจต้องการให้เมธอดของคุณมีIllegalArgumentExceptionค่าเป็นโมฆะ สัญญาณนี้จะส่งสัญญาณไปยังผู้เรียกใช้ของวิธีการที่บั๊กอยู่ในรหัสของพวกเขา (แทนที่จะเป็นวิธีของตัวเอง)
ไบรอัน

20

อย่าใช้ null ให้ใช้ตัวเลือก

ดังที่คุณได้ชี้ให้เห็นแล้วหนึ่งในปัญหาที่ใหญ่ที่สุดnullใน Java คือมันสามารถใช้ได้ทุกที่หรืออย่างน้อยก็สำหรับการอ้างอิงทุกประเภท

เป็นไปไม่ได้ที่จะบอกได้ว่าอาจเป็นnullและสิ่งที่เป็นไปไม่ได้

Java 8 Optionalเปิดตัวรูปแบบที่ดีมาก:

และตัวอย่างจาก Oracle:

String version = "UNKNOWN";
if(computer != null) {
  Soundcard soundcard = computer.getSoundcard();
  if(soundcard != null) {
    USB usb = soundcard.getUSB();
    if(usb != null) {
      version = usb.getVersion();
    }
  }
}

หากแต่ละสิ่งเหล่านี้อาจหรือไม่อาจส่งกลับค่าที่ประสบความสำเร็จคุณสามารถเปลี่ยน API Optionalเป็น:

String name = computer.flatMap(Computer::getSoundcard)
    .flatMap(Soundcard::getUSB)
    .map(USB::getVersion)
    .orElse("UNKNOWN");

โดยการเข้ารหัสทางเลือกอย่างชัดเจนในประเภทอินเทอร์เฟซของคุณจะดีขึ้นมากและรหัสของคุณจะสะอาดขึ้น

หากคุณไม่ได้ใช้ Java 8 คุณสามารถดูได้com.google.common.base.Optionalใน Google Guava

คำอธิบายที่ดีจากทีม Guava: https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained

คำอธิบายทั่วไปของข้อเสียเป็นโมฆะโดยมีตัวอย่างจากหลายภาษา: https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/


@Nullull, @Nullable

Java 8 เพิ่มหมายเหตุประกอบเหล่านี้เพื่อช่วยให้เครื่องมือตรวจสอบโค้ดเช่น IDEs ตรวจพบปัญหา พวกมันค่อนข้างมีประสิทธิภาพ จำกัด


ตรวจสอบเมื่อมันทำให้รู้สึก

อย่าเขียนโค้ด 50% ของการตรวจสอบค่าว่างโดยเฉพาะอย่างยิ่งหากไม่มีสิ่งที่เหมาะสมที่รหัสของคุณสามารถทำได้ด้วยnullค่า

ในทางกลับกันหากnullสามารถใช้งานและหมายถึงบางสิ่งได้


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


2
โดยปกติแล้วคำตอบของคำถามสี่ปีจะถูกลบเนื่องจากคุณภาพต่ำ เก่งมากที่พูดถึงว่า Java 8 (ซึ่งไม่มีอยู่ในตอนนั้น) สามารถแก้ปัญหาได้อย่างไร

แต่ไม่เกี่ยวข้องกับคำถามดั้งเดิมแน่นอน และสิ่งที่จะบอกว่าการโต้แย้งเป็นตัวเลือกที่แน่นอน?
jwenting

5
@ jwenting มันเกี่ยวข้องกับคำถามเดิมอย่างสมบูรณ์ คำตอบของ "วิธีที่ดีที่สุดในการขับเล็บด้วยไขควง" คือ "ใช้ค้อนแทนไขควง"
Daenyth

@ jwenting ฉันคิดว่าฉันครอบคลุม แต่สำหรับความชัดเจน: เป็นข้อโต้แย้งที่ไม่จำเป็นฉันมักจะไม่ตรวจสอบเป็นโมฆะ คุณจะมีการตรวจสอบ null 100 บรรทัดและ 40 บรรทัดของสาร ตรวจสอบโมฆะที่อินเทอร์เฟซสาธารณะมากขึ้นหรือเมื่อใดที่โมฆะสมเหตุสมผลจริง ๆ
Paul Draper

4
@ J-Boss เป็นอย่างไรใน Java คุณจะไม่ได้ถูกตรวจสอบNullPointerException? A NullPointerExceptionสามารถเกิดขึ้นได้อย่างแท้จริง ทุกครั้งที่คุณเรียกใช้เมธอดอินสแตนซ์ใน Java คุณจะมีthrows NullPointerExceptionวิธีเกือบทุกวิธีเลยทีเดียว
พอลเดรเปอร์

8

มีหลายวิธีในการจัดการกับปัญหานี้โค้ดของคุณif (obj != null) {}ไม่เหมาะมันยุ่งเหยิงเพิ่มเสียงเมื่ออ่านรหัสในระหว่างรอบการบำรุงรักษาและเกิดข้อผิดพลาดได้ง่ายเนื่องจากลืมการห่อแผ่นหม้อไอน้ำนี้ได้ง่าย

ขึ้นอยู่กับว่าคุณต้องการให้โค้ดทำงานต่อไปอย่างเงียบ ๆ หรือล้มเหลว เป็นnullข้อผิดพลาดหรือสภาพที่คาดว่า

เป็นโมฆะอะไร

ในทุก ๆ การกำหนดและกรณีNullแสดงถึงการขาดข้อมูลที่แน่นอน Nulls ในฐานข้อมูลแสดงถึงการขาดค่าสำหรับคอลัมน์นั้น ค่าว่างStringไม่เหมือนกับค่าว่างเปล่าStringค่าว่างintไม่เหมือนกับค่าศูนย์ในทางทฤษฎี ในทางปฏิบัติ "มันขึ้นอยู่กับ" Empty Stringสามารถสร้างการNull Objectใช้งานที่ดีสำหรับคลาส String Integerขึ้นอยู่กับตรรกะทางธุรกิจ

ทางเลือกคือ:

  1. เรื่องของNull Objectลวดลาย สร้างอินสแตนซ์ของวัตถุของคุณที่แสดงถึงnullสถานะและเริ่มต้นการอ้างอิงทั้งหมดไปยังประเภทนั้นด้วยการอ้างอิงถึงการNullใช้งาน สิ่งนี้มีประโยชน์สำหรับวัตถุประเภทค่าอย่างง่ายที่ไม่มีการอ้างอิงไปยังวัตถุอื่นที่อาจเป็นnullและคาดว่าจะnullเป็นสถานะที่ถูกต้อง

  2. ใช้เครื่องมือที่เน้นแนวยาวเพื่อสานวิธีด้วยNull Checkerลักษณะที่ป้องกันพารามิเตอร์ไม่ให้เป็นค่าว่าง สำหรับกรณีที่nullเกิดข้อผิดพลาด

  3. ใช้assert()ไม่ได้ดีไปกว่าif (obj != null){}เสียงรบกวน แต่น้อย

  4. ใช้เครื่องมือการบังคับใช้สัญญาเช่นสัญญาสำหรับ Java กรณีการใช้งานเช่นเดียวกับ AspectJ แต่ใหม่กว่าและใช้คำอธิบายประกอบแทนไฟล์กำหนดค่าภายนอก สุดยอดของผลงานทั้งด้านและการยืนยัน

1 เป็นโซลูชันที่เหมาะสมที่สุดเมื่อทราบว่ามีข้อมูลขาเข้าnullและจำเป็นต้องถูกแทนที่ด้วยค่าเริ่มต้นบางส่วนเพื่อให้ผู้ใช้ที่อัปสตรีมไม่จำเป็นต้องจัดการกับโค้ด null ที่ตรวจสอบได้ทั้งหมด การตรวจสอบกับค่าเริ่มต้นที่รู้จักจะมีความชัดเจนมากขึ้นเช่นกัน

2, 3 และ 4 เป็นเพียงตัวสร้างข้อยกเว้นทางเลือกที่สะดวกในการแทนที่NullPointerExceptionด้วยข้อมูลที่มากขึ้นซึ่งจะเป็นการปรับปรุงอยู่เสมอ

ในที่สุด

nullใน Java เกือบทุกกรณีมีข้อผิดพลาดเชิงตรรกะ NullPointerExceptionsคุณควรมุ่งมั่นที่จะกำจัดสาเหตุของ คุณควรพยายามอย่าใช้nullเงื่อนไขเป็นตรรกะทางธุรกิจ if (x == null) { i = someDefault; }เพียงกำหนดค่าเริ่มต้นให้กับอินสแตนซ์ของวัตถุนั้น


หากเป็นไปได้รูปแบบวัตถุ null เป็นวิธีการมันเป็นวิธีที่สง่างามที่สุดในการจัดการกรณีเป็นโมฆะ หายากที่คุณต้องการให้ null เพื่อทำให้สิ่งของระเบิดในการผลิต!
Richard Miskin

@ ริชาร์ด: ถ้าnullไม่คาดคิดก็เป็นข้อผิดพลาดจริงทุกอย่างก็จะหยุดชะงัก

Null ในฐานข้อมูลและในรหัสการเขียนโปรแกรมมีการจัดการที่แตกต่างกันในด้านที่สำคัญอย่างหนึ่ง: ในการเขียนโปรแกรมnull == null(แม้ใน PHP) แต่ในฐานข้อมูลnull != nullเพราะในฐานข้อมูลมันแสดงถึงค่าที่ไม่รู้จักแทน "ไม่มีอะไร" สองนิรนามนั้นไม่จำเป็นต้องเท่ากันในขณะที่สองสิ่งนั้นไม่เท่ากัน
Simon Forsberg

8

การเพิ่มการตรวจสอบ null อาจทำให้การทดสอบมีปัญหา ดูการบรรยายที่ยอดเยี่ยมนี้ ...

ลองดูการบรรยายของ Google Tech Talk: "The Clean Code Talks - อย่ามองหาสิ่งต่าง ๆ !" เขาพูดเกี่ยวกับมันประมาณ 24 นาที

http://www.youtube.com/watch?v=RlfLCWKxHJ0&list=PL693EFD059797C21E

การเขียนโปรแกรมหวาดระแวงเกี่ยวข้องกับการเพิ่มการตรวจสอบเป็นโมฆะทุกที่ ดูเหมือนว่าความคิดที่ดีในตอนแรกอย่างไรก็ตามจากมุมมองการทดสอบมันทำให้การตรวจสอบประเภท null ของคุณทดสอบยากที่จะจัดการ

นอกจากนี้เมื่อคุณสร้างเงื่อนไขเบื้องต้นสำหรับการมีอยู่ของวัตถุบางอย่างเช่น

class House(Door door){

    .. null check here and throw exception if Door is NULL
    this.door = door
}

มันป้องกันคุณจากการสร้างบ้านเนื่องจากคุณจะได้รับการยกเว้น สมมติว่ากรณีทดสอบของคุณกำลังสร้างวัตถุจำลองสำหรับการทดสอบอย่างอื่นที่นอกเหนือจากประตูดีคุณไม่สามารถทำได้เพราะต้องมีประตู

ผู้ที่ได้รับความเดือดร้อนจากการสร้างเยาะเย้ยจากนรกก็ตระหนักดีถึงความน่ารำคาญเหล่านี้

โดยสรุปชุดทดสอบของคุณควรแข็งแกร่งพอที่จะทดสอบประตูบ้านหลังคาหรืออะไรก็ได้โดยไม่ต้องหวาดระแวง ในความเป็นจริงมันยากแค่ไหนที่จะเพิ่มการทดสอบการตรวจสอบว่างสำหรับวัตถุเฉพาะในการทดสอบของคุณ :)

คุณควรเลือกแอปพลิเคชั่นที่ใช้งานได้เพราะคุณมีการทดสอบหลายอย่างที่พิสูจน์ได้ว่ามันใช้งานได้มากกว่าที่จะ HOPING มันใช้งานได้ง่ายเพราะคุณมีการตรวจสอบ null แบบไม่มีเงื่อนไขทั้งหมด


4

tl; dr - เป็นการดีที่จะตรวจสอบสิ่งที่ไม่คาดคิดnullแต่ BAD สำหรับแอปพลิเคชันเพื่อพยายามทำให้ดีขึ้น

รายละเอียด

เห็นได้ชัดว่ามีสถานการณ์ที่nullเป็นอินพุตหรือเอาต์พุตที่ถูกต้องไปยังเมธอดและอื่น ๆ ที่ไม่มี

กฎ # 1:

javadoc สำหรับวิธีการที่อนุญาตให้nullพารามิเตอร์หรือส่งคืนnullค่าต้องมีเอกสารชัดเจนและอธิบายความnullหมาย

กฎ # 2:

ไม่ควรระบุวิธีการ API เป็นการยอมรับหรือส่งคืนnullยกเว้นว่ามีเหตุผลที่ดีในการทำเช่นนั้น

ด้วยข้อกำหนดที่ชัดเจนของ "สัญญา" ของเมธอด vis-a-vis nullมันเป็นข้อผิดพลาดในการเขียนโปรแกรมเพื่อส่งหรือส่งคืนnullตำแหน่งที่คุณไม่ควรทำ

กฎ # 3:

แอปพลิเคชันไม่ควรพยายามที่จะ "ผิดพลาด" การเขียนโปรแกรมผิดพลาด

หากวิธีการตรวจพบnullว่าไม่ควรอยู่ที่นั่นก็ไม่ควรพยายามแก้ไขปัญหาด้วยการเปลี่ยนเป็นวิธีอื่น นั่นเป็นเพียงการซ่อนปัญหาจากโปรแกรมเมอร์ แต่ควรอนุญาตให้ NPE เกิดขึ้นและทำให้เกิดความล้มเหลวเพื่อให้โปรแกรมเมอร์สามารถทราบสาเหตุที่แท้จริงและแก้ไขได้ หวังว่าความล้มเหลวจะถูกสังเกตในระหว่างการทดสอบ ถ้าไม่เช่นนั้นจะบอกบางอย่างเกี่ยวกับวิธีการทดสอบของคุณ

กฎ # 4:

หากเป็นไปได้ให้เขียนรหัสของคุณเพื่อตรวจหาข้อผิดพลาดในการเขียนโปรแกรมล่วงหน้า

หากคุณมีข้อบกพร่องในรหัสของคุณซึ่งส่งผลให้มี NPE จำนวนมากสิ่งที่ยากที่สุดคือการหาว่าnullค่ามาจากไหน วิธีหนึ่งในการทำให้การวินิจฉัยง่ายขึ้นคือการเขียนโค้ดของคุณเพื่อให้nullตรวจพบโดยเร็วที่สุด บ่อยครั้งที่คุณสามารถทำสิ่งนี้ร่วมกับเช็คอื่น ๆ เช่น

public setName(String name) {
    // This also detects `null` as an (intended) side-effect
    if (name.length() == 0) {
        throw new IllegalArgumentException("empty name");
    }
}

(มีบางกรณีที่กฎ 3 และ 4 ควรมีอารมณ์เป็นจริงตัวอย่างเช่น (กฎ 3) แอปพลิเคชันบางประเภทต้องพยายามดำเนินการต่อหลังจากตรวจพบข้อผิดพลาดในการเขียนโปรแกรมที่อาจเกิดขึ้นและ (กฎ 4) การตรวจสอบพารามิเตอร์ที่ไม่เหมาะสมมากเกินไป ผลกระทบต่อประสิทธิภาพ)


3

ฉันอยากจะแนะนำให้แก้ไขวิธีการป้องกัน ตัวอย่างเช่น

String go(String s){  
    return s.toString();  
}

ควรมีมากขึ้นตามแนวนี้:

String go(String s){  
    if(s == null){  
       return "";  
    }     
    return s.toString();  
}

ฉันรู้ว่านี่เป็นเรื่องเล็กน้อยอย่างแน่นอน แต่หากผู้เรียกคาดหวังว่าวัตถุให้วัตถุเริ่มต้นแก่พวกเขาซึ่งจะไม่ทำให้เกิดการว่างเปล่า


10
สิ่งนี้มีผลข้างเคียงที่น่ารังเกียจในกรณีที่ผู้เรียก (โปรแกรมเมอร์ที่ใช้รหัสกับ API นี้) อาจพัฒนานิสัยในการส่งผ่านค่า null เป็นพารามิเตอร์เพื่อรับพฤติกรรม "เริ่มต้น"
Goran Jovic

2
หากนี่คือ Java คุณไม่ควรใช้new String()งานเลย
biziclop

1
@biziclop จริงๆแล้วมันสำคัญกว่าการตระหนักมากที่สุด
Woot4Moo

1
ในความคิดของฉันมันสมเหตุสมผลกว่าที่จะวางการยืนยันและโยนข้อยกเว้นถ้าอาร์กิวเมนต์เป็นโมฆะเนื่องจากเป็นความผิดพลาดของผู้โทรอย่างชัดเจน อย่า "แก้ไข" ข้อผิดพลาดของผู้โทรเข้าเงียบ ๆ แต่ให้พวกเขาตระหนักถึงพวกเขาแทน
Andres F.

1
@ Woot4Moo ดังนั้นให้เขียนโค้ดของคุณเองที่ทำให้เกิดข้อยกเว้น สิ่งสำคัญคือการแจ้งให้ผู้โทรทราบว่าข้อโต้แย้งที่ส่งไปนั้นผิดและบอกพวกเขาโดยเร็วที่สุด การแก้ไขอย่างเงียบnullๆ คือทางเลือกที่แย่ที่สุดที่เป็นไปได้แย่กว่าการโยน NPE
Andres F.

2

กฎทั่วไปต่อไปนี้เกี่ยวกับ null ช่วยฉันได้มากจนถึงตอนนี้:

  1. หากข้อมูลนั้นมาจากนอกการควบคุมของคุณให้ตรวจสอบ nulls อย่างเป็นระบบและดำเนินการอย่างเหมาะสม ซึ่งหมายถึงการโยนข้อยกเว้นที่เหมาะสมกับฟังก์ชั่น (เลือกหรือไม่เลือกเพียงตรวจสอบให้แน่ใจว่าชื่อของข้อยกเว้นบอกคุณอย่างชัดเจนว่าเกิดอะไรขึ้น) แต่จะไม่ทำให้ค่าในระบบของคุณสูญเสียไปซึ่งอาจทำให้เกิดความประหลาดใจได้

  2. หาก Null อยู่ในโดเมนของค่าที่เหมาะสมสำหรับตัวแบบข้อมูลของคุณให้จัดการกับมันอย่างเหมาะสม

  3. เมื่อส่งคืนค่าพยายามที่จะไม่คืน nulls เมื่อใดก็ตามที่เป็นไปได้ ชอบรายการเปล่าสตริงว่างรูปแบบวัตถุ Null เสมอ เก็บค่า Null ไว้เป็นค่าที่ส่งคืนเมื่อเป็นการนำเสนอข้อมูลที่ดีที่สุดสำหรับกรณีการใช้งานที่กำหนด

  4. อาจเป็นสิ่งที่สำคัญที่สุดของทั้งหมด ... การทดสอบการทดสอบและการทดสอบอีกครั้ง เมื่อทำการทดสอบโค้ดของคุณอย่าทดสอบมันเป็น coder ทดสอบว่าเป็น dominatrix นักจิตวิทยาของนาซีและลองจินตนาการถึงวิธีการทุกชนิดที่จะทรมานนรกจากโค้ดนั้น

สิ่งนี้มีแนวโน้มเล็กน้อยที่ด้านหวาดระแวงเกี่ยวกับโมฆะมักจะนำไปสู่ส่วนหน้าและพร็อกซีที่ระบบอินเทอร์เฟซไปสู่โลกภายนอก โลกภายนอกที่นี่หมายถึงทุกสิ่งที่ฉันไม่ได้เขียนเอง มันมีค่าใช้จ่ายรันไทม์ แต่จนถึงตอนนี้ฉันแทบจะไม่ต้องปรับให้เหมาะสมด้วยการสร้าง "ส่วนที่ปลอดภัยเป็นโมฆะ" ของรหัส ฉันต้องบอกว่าส่วนใหญ่ฉันสร้างระบบที่ใช้เวลานานสำหรับการดูแลสุขภาพและสิ่งสุดท้ายที่ฉันต้องการคือระบบย่อยของอินเทอร์เฟซที่มีอาการแพ้ไอโอดีนของคุณไปยังเครื่องสแกน CT เกิดปัญหาเนื่องจากตัวชี้โมฆะ null ที่ไม่คาดฝัน มีเครื่องหมายวรรคตอนหรือตัวอักษรเช่น characters 耒耨。

อย่างไรก็ตาม .... 2 เซ็นต์ของฉัน


1

ฉันจะเสนอให้ใช้รูปแบบตัวเลือก / บาง / ไม่มีจากภาษาที่ใช้งานได้ ฉันไม่ใช่ผู้เชี่ยวชาญเกี่ยวกับ Java แต่ฉันใช้การใช้รูปแบบนี้อย่างเข้มข้นในโครงการ C # ของฉันและฉันมั่นใจว่าสามารถแปลงเป็นโลก Java ได้

แนวคิดเบื้องหลังรูปแบบนี้คือ: หากมีเหตุผลที่จะมีสถานการณ์เมื่อมีความเป็นไปได้ที่จะไม่มีค่า (ตัวอย่างเช่นเมื่อเรียกจากฐานข้อมูลโดยใช้ id) คุณให้วัตถุประเภท [Option] โดยที่ T เป็นค่าที่เป็นไปได้ . ฉันกรณีที่ไม่มีตัวตนของวัตถุที่มีค่าของคลาสไม่มี [T] กลับมาในกรณีที่การดำรงอยู่ของค่า - วัตถุของบาง [T] กลับมามีค่า

ในกรณีนี้คุณต้องจัดการกับความเป็นไปได้ของการไม่มีค่าและถ้าคุณทำการตรวจสอบโค้ดคุณสามารถพบ placec ของการจัดการที่ไม่ถูกต้องได้อย่างง่ายดาย หากต้องการรับแรงบันดาลใจจากการใช้งานภาษา C # อ้างอิงไปยังที่เก็บ bitbucket ของฉันhttps://bitbucket.org/mikegirkin/optionsomenone

หากคุณส่งคืนค่า Null และมีค่าเท่ากับตรรกะถึงข้อผิดพลาด (ตัวอย่างเช่นไม่มีไฟล์หรือไม่สามารถเชื่อมต่อได้) คุณควรโยนข้อยกเว้นหรือใช้รูปแบบการจัดการข้อผิดพลาดอื่น แนวคิดที่อยู่เบื้องหลังสิ่งนี้อีกครั้งคุณจะจบลงด้วยวิธีแก้ปัญหาเมื่อคุณต้องจัดการกับสถานการณ์ที่ไม่มีคุณค่าและสามารถหาสถานที่จัดการที่ไม่ถูกต้องในรหัสได้อย่างง่ายดาย


0

ถ้าหนึ่งในผลลัพธ์ที่เป็นไปได้ของวิธีการของคุณคือค่า Null คุณควรเขียนโค้ดป้องกันไว้อย่างนั้น แต่ถ้าวิธีใดที่ควรจะคืนค่าที่ไม่เป็นโมฆะ

ตามปกติมันขึ้นอยู่กับกรณีเช่นเดียวกับสิ่งส่วนใหญ่ในชีวิต :)


0

ไลบรารีlangของ Apache Commons จัดเตรียมวิธีการจัดการกับค่า Null

เมธอดdefaultIfNullในคลาสObjectUtilsช่วยให้คุณส่งคืนค่าเริ่มต้นหากวัตถุที่ส่งผ่านเป็นโมฆะ


0
  1. อย่าใช้ตัวเลือกเว้นแต่จะเป็นตัวเลือกอย่างแท้จริงบ่อยครั้งที่ทางออกจะจัดการได้ดีกว่าเป็นข้อยกเว้นเว้นแต่ว่าคุณคาดหวังว่าจะเป็นตัวเลือกที่เป็นโมฆะและไม่ใช่เพราะคุณเขียนรหัสบั๊กกี้เป็นประจำ

  2. ปัญหาไม่เป็นโมฆะเนื่องจากเป็นประเภทที่มีการใช้งานตามที่บทความของ Google ระบุไว้ ปัญหาคือควรตรวจสอบและจัดการ nulls บ่อยครั้งที่พวกเขาสามารถออกได้อย่างสง่างาม

  3. มีหลายกรณีที่แสดงถึงเงื่อนไขที่ไม่ถูกต้องในพื้นที่ภายนอกการดำเนินงานตามปกติของโปรแกรม (อินพุตผู้ใช้ไม่ถูกต้อง, ปัญหาฐานข้อมูล, เครือข่ายล้มเหลว, ไฟล์ที่หายไป, ข้อมูลเสียหาย) ซึ่งเป็นข้อยกเว้นที่ตรวจสอบเพื่อจัดการกับพวกเขา ถ้ามันเป็นเพียงการเข้าสู่ระบบ

  4. การจัดการข้อยกเว้นได้รับอนุญาตให้ลำดับความสำคัญและสิทธิประโยชน์ในการดำเนินงานที่แตกต่างกันใน JVM เมื่อเทียบกับประเภทเช่นตัวเลือกที่เหมาะสมสำหรับลักษณะพิเศษของการเกิดขึ้นรวมถึงการสนับสนุนในช่วงต้นสำหรับการโหลดสันหลังยาว ต้องการมันแขวนอยู่ตลอดเวลา

  5. คุณไม่จำเป็นต้องเขียนตัวจัดการโมฆะทั่วสถานที่เท่านั้นที่พวกเขามีแนวโน้มที่จะเกิดขึ้นทุกที่ที่คุณอาจเข้าถึงบริการข้อมูลที่ไม่น่าเชื่อถือและเนื่องจากส่วนใหญ่เหล่านี้ตกอยู่ในรูปแบบทั่วไปไม่กี่ที่สามารถใจลอยคุณต้องการเท่านั้น การเรียกใช้ตัวจัดการยกเว้นในบางกรณี

ดังนั้นฉันเดาว่าคำตอบของฉันจะถูกห่อด้วยข้อยกเว้นที่ตรวจสอบและจัดการมันหรือแก้ไขรหัสที่ไม่น่าเชื่อถือหากมันอยู่ในความสามารถของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.