ทำไมเมื่อฉันพยายามสร้าง ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
มีข้อผิดพลาดและ java ไม่อนุญาตสิ่งนี้
มีเหตุผลที่เกี่ยวข้องกับการใช้งาน generics ของจาวา, generics ในภาษาใด ๆ หรือบางสิ่งบางอย่างโดยพลการ?
ทำไมเมื่อฉันพยายามสร้าง ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
มีข้อผิดพลาดและ java ไม่อนุญาตสิ่งนี้
มีเหตุผลที่เกี่ยวข้องกับการใช้งาน generics ของจาวา, generics ในภาษาใด ๆ หรือบางสิ่งบางอย่างโดยพลการ?
คำตอบ:
นี้เป็นหนึ่งในหลุมที่สำคัญในยาชื่อสามัญของ Java อาร์เรย์มีcovariantหมายความว่าอาร์เรย์ของชนิดFoo[]
เป็น subclass ของและObject[]
ParentOfFoo[]
ตัดกับสิ่งนี้List<Foo>
ซึ่งไม่มีพฤติกรรมนี้
สิ่งนี้สำคัญเมื่อ Java ไม่มี generics (จนถึง Java 5) เพราะมิฉะนั้นบางอย่างเช่นฟังก์ชั่นการจัดเรียงทั่วไปก็เป็นไปไม่ได้
แต่ก็มีปัญหายุ่งยากที่อาร์เรย์ต้องการที่จะรู้ว่าสิ่งที่พวกเขาจะพิมพ์ที่รันไทม์ อย่างไรก็ตามข้อมูลทั่วไปใน Java ขึ้นอยู่กับการลบประเภท สองสิ่งนี้ไม่สอดคล้องกันและนั่นคือสิ่งที่เราได้รับปัญหาของเรา
ดังนั้นความยาวและสั้นของมันคือใน Java 1 อาร์เรย์ covariant เติมเต็มบางส่วนของหลุมที่ไม่มีการสร้าง generics ขึ้น อย่างไรก็ตามเมื่อพวกเขาพยายามเติมหลุมนี้อย่างถูกต้องความเข้ากันได้แบบย้อนกลับนั่นหมายความว่าอาร์เรย์นั้นเป็นไปไม่ได้ที่จะนำมาใช้
อันที่จริงคนที่สร้างกรอบการทำงานของนายพลมาร์ตินโอชสกี้พูดถึงเรื่องนี้ที่นี่ในระหว่างการสัมภาษณ์ว่าทำไมเขาถึงสร้างสคาล่า (น่าสนใจมากถ้าคุณสนใจประวัติของสกาล่าเลย)
มีเหตุผลที่เกี่ยวข้องกับการใช้งาน generics ของจาวา, generics ในภาษาใด ๆ หรือบางสิ่งบางอย่างโดยพลการ?
ที่จริงแล้วมันค่อนข้างโดยพลการ
ปัญหาคือว่ามันจะช่วยให้หลุมในระบบการพิมพ์เพราะArrayList<T>[]
สามารถที่จะหล่อObject[]
และจากนั้นคุณสามารถใส่ในอาร์เรย์ที่ArrayList<U>
U != T
นักออกแบบ Java ตัดสินใจบล็อกรูนี้อย่างกระตือรือร้นที่สุดโดยไม่อนุญาตnew ArrayList<T>[N]
เลย
อย่างไรก็ตามอาจมีการเสียบโดยไม่อนุญาตให้อัปโหลดอาร์เรย์ของ generics (โดยไม่มีคำเตือน "ไม่ถูกตรวจสอบ")
Integer
เข้าไปในObject[]
ที่เป็นจริงString[]
เนื่องจากอาร์เรย์เป็น covariantซึ่งทุกประเภทเป็นคลาสย่อยของวัตถุดังนั้นสิ่งนี้จะทำให้เกิดข้อผิดพลาดในเวลาทำงานเนื่องจากข้อยกเว้นการคัดเลือก ในขณะที่ทั่วไปเป็นค่าคงที่ดังนั้นเมื่อมันสร้างบนพิมพ์มั่นใจหรือปลอดภัยประเภทดังนั้นหากประเภทไม่ชอบมันสร้างประเภทมันให้ข้อผิดพลาดคอมไพเลอร์