กฎนี้มีวัตถุประสงค์เพื่อหลีกเลี่ยงความขัดแย้งในรหัสดั้งเดิมที่ยังคงใช้ประเภทดิบ
นี่คือภาพประกอบว่าทำไมสิ่งนี้จึงไม่ได้รับอนุญาตดึงมาจาก JLS สมมติว่าก่อนที่ generics จะแนะนำให้รู้จักกับ Java ฉันเขียนโค้ดบางอย่างเช่นนี้:
class CollectionConverter {
List toList(Collection c) {...}
}
คุณขยายชั้นเรียนของฉันเช่นนี้
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
หลังจากการแนะนำ generics ฉันตัดสินใจที่จะปรับปรุงห้องสมุดของฉัน
class CollectionConverter {
<T> List<T> toList(Collection<T> c) {...}
}
คุณยังไม่พร้อมที่จะทำการอัพเดทใด ๆ ดังนั้นคุณจึงออกจากOverrider
ชั้นเรียนเพียงลำพัง เพื่อที่จะลบล้างtoList()
วิธีการได้อย่างถูกต้องนักออกแบบภาษาตัดสินใจว่าประเภท raw นั้น "override-สมมูล" กับชนิดที่สร้างขึ้นใด ๆ ซึ่งหมายความว่าแม้ว่าลายเซ็นวิธีการของคุณจะไม่เป็นทางการเท่ากับลายเซ็น superclass ของฉันอีกต่อไปวิธีการของคุณยังคงแทนที่
เวลาผ่านไปและคุณตัดสินใจว่าคุณพร้อมที่จะอัปเดตชั้นเรียนของคุณ แต่คุณทำผิดพลาดเล็กน้อยและแทนที่จะแก้ไขtoList()
วิธีraw ที่มีอยู่เดิมคุณเพิ่มวิธีการใหม่ดังนี้:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
เนื่องจากความเท่าเทียมกันของการแทนที่ประเภทดิบทั้งสองวิธีอยู่ในรูปแบบที่ถูกต้องเพื่อแทนที่toList(Collection<T>)
วิธีการ แต่แน่นอนว่าคอมไพเลอร์จำเป็นต้องแก้ไขวิธีการเดียว เพื่อกำจัดความกำกวมนี้คลาสไม่ได้รับอนุญาตให้มีหลายวิธีที่เทียบเท่ากับการแทนที่นั่นคือหลายวิธีที่มีพารามิเตอร์ชนิดเดียวกันหลังจากลบออก
กุญแจสำคัญคือนี่เป็นกฎภาษาที่ออกแบบมาเพื่อรักษาความเข้ากันได้กับรหัสเดิมโดยใช้ชนิดข้อมูลดิบ ไม่ใช่ข้อ จำกัด ที่ต้องการโดยการลบพารามิเตอร์ชนิด เนื่องจากวิธีแก้ไขปัญหาเกิดขึ้นในเวลาคอมไพล์การเพิ่มประเภททั่วไปลงในตัวระบุวิธีการจะเพียงพอ