จำเป็นต้องยกเลิกการทำกล่องอัตโนมัติของบุคคลที่สามถ้าอื่น


23

รหัสชิ้นนี้ทำงานได้ดี: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

แต่สิ่งนี้จะทำให้เกิดข้อยกเว้นตัวชี้โมฆะในขณะที่ Eclipse เตือนว่าไม่จำเป็นต้องทำการแกะกล่องโดยอัตโนมัติ: -

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

ทำไมถึงเป็นเช่นนั้นใครบางคนสามารถนำทางได้โปรด

คำตอบ:


22

ชนิดของนิพจน์เงื่อนไขแบบไตรภาค

1 <= 3 ? nullInt : -1

คือint(JLS มีหลายตารางที่อธิบายประเภทของตัวดำเนินการเงื่อนไขแบบไตรภาคขึ้นอยู่กับชนิดของตัวถูกดำเนินการที่สองและที่สาม)

ดังนั้นเมื่อมันพยายามที่จะ unbox nullIntไปที่inta NullPointerExceptionก็จะถูกโยนทิ้งไป

ในการรับพฤติกรรมของข้อมูลโค้ด if-else ของคุณคุณต้องเขียน:

1 <= 3 ? nullInt : Integer.valueOf(-1)

ตอนนี้ประเภทของนิพจน์จะเป็นIntegerเช่นนั้นดังนั้นจะไม่มีการแกะกล่องออกมา


4
เพียงเพิ่มคำตอบของคุณนี่คือตารางที่กล่าวถึง: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

ฉันค่อนข้างแน่ใจว่าการขัดแย้งกับผู้ประกอบการที่ต้องประกอบไปด้วยประเภทเดียวกันนี้ เนื่องจากคุณใช้ -1 และnullintคอมไพเลอร์คงที่บางตัวพยายามที่จะ unbox nullintเพื่อรับค่า จากนั้นก็ทำการล็อกอัตโนมัติเพื่อเก็บไว้ในsecondNullตัวแปร


3

นี่เป็นเพราะเมื่อตัวถูกดำเนินการสองตัวสำหรับตัวดำเนินการตามเงื่อนไข? :เป็นชนิดดั้งเดิมและชนิดการอ้างอิงชนิดบรรจุกล่องจะทำการแปลงแบบไม่แกะกล่อง ( JLS §15.25.2 ):

ชนิดของนิพจน์เงื่อนไขที่เป็นตัวเลขถูกกำหนดดังนี้:

  • ...
  • หากหนึ่งในตัวถูกดำเนินการที่สองและสามเป็นประเภทดั้งเดิม T และประเภทอื่น ๆ เป็นผลมาจากการใช้การแปลงมวย (§5.1.7) เป็น T แล้วประเภทของนิพจน์เงื่อนไขคือ T

โดยทั่วไปการแทนที่ifคำสั่งด้วย? :นิพจน์นั้นไม่ได้รักษาความหมายของรหัสไว้เสมอไปเนื่องจาก? :นิพจน์นั้นจำเป็นต้องมีประเภทเวลาคอมไพล์ นั่นหมายความว่าเมื่อชนิดของตัวถูกดำเนินการทั้งสองแตกต่างกันการแปลงจะต้องทำอย่างใดอย่างหนึ่งหรือทั้งสองอย่างเพื่อให้ผลลัพธ์มีประเภทเวลาคอมไพล์ที่สอดคล้องกัน


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