ทำไม java generics ไม่สามารถอยู่ในอาร์เรย์ได้?


10

ทำไมเมื่อฉันพยายามสร้าง ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];มีข้อผิดพลาดและ java ไม่อนุญาตสิ่งนี้

มีเหตุผลที่เกี่ยวข้องกับการใช้งาน generics ของจาวา, generics ในภาษาใด ๆ หรือบางสิ่งบางอย่างโดยพลการ?


คำตอบ:


20

นี้เป็นหนึ่งในหลุมที่สำคัญในยาชื่อสามัญของ Java อาร์เรย์มีcovariantหมายความว่าอาร์เรย์ของชนิดFoo[]เป็น subclass ของและObject[] ParentOfFoo[]ตัดกับสิ่งนี้List<Foo>ซึ่งไม่มีพฤติกรรมนี้

สิ่งนี้สำคัญเมื่อ Java ไม่มี generics (จนถึง Java 5) เพราะมิฉะนั้นบางอย่างเช่นฟังก์ชั่นการจัดเรียงทั่วไปก็เป็นไปไม่ได้

แต่ก็มีปัญหายุ่งยากที่อาร์เรย์ต้องการที่จะรู้ว่าสิ่งที่พวกเขาจะพิมพ์ที่รันไทม์ อย่างไรก็ตามข้อมูลทั่วไปใน Java ขึ้นอยู่กับการลบประเภท สองสิ่งนี้ไม่สอดคล้องกันและนั่นคือสิ่งที่เราได้รับปัญหาของเรา

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

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


3

มีเหตุผลที่เกี่ยวข้องกับการใช้งาน generics ของจาวา, generics ในภาษาใด ๆ หรือบางสิ่งบางอย่างโดยพลการ?

ที่จริงแล้วมันค่อนข้างโดยพลการ

ปัญหาคือว่ามันจะช่วยให้หลุมในระบบการพิมพ์เพราะArrayList<T>[]สามารถที่จะหล่อObject[]และจากนั้นคุณสามารถใส่ในอาร์เรย์ที่ArrayList<U>U != T

นักออกแบบ Java ตัดสินใจบล็อกรูนี้อย่างกระตือรือร้นที่สุดโดยไม่อนุญาตnew ArrayList<T>[N]เลย

อย่างไรก็ตามอาจมีการเสียบโดยไม่อนุญาตให้อัปโหลดอาร์เรย์ของ generics (โดยไม่มีคำเตือน "ไม่ถูกตรวจสอบ")


คำตอบนี้ถูกประเมินค่าน้อยเกินไป ง่ายมากและไม่ใช้ศัพท์แสงในแง่ที่คลุมเครือ ขอบคุณมาก ๆ.
ตุงเหงียน

คุณอาจต้องการที่จะอธิบายอย่างละเอียดว่าทำไมถึงแตกต่างกับกรณีที่คุณใส่Integerเข้าไปในObject[]ที่เป็นจริงString[]
Caleth

-3

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

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