Quy tắc này nhằm tránh xung đột trong mã kế thừa vẫn sử dụng các loại thô.
Đây là một minh họa về lý do tại sao điều này không được phép, được rút ra từ JLS. Giả sử, trước khi thuốc generic được giới thiệu cho Java, tôi đã viết một số mã như thế này:
class CollectionConverter {
List toList(Collection c) {...}
}
Bạn mở rộng lớp học của tôi, như thế này:
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
Sau khi giới thiệu thuốc generic, tôi quyết định cập nhật thư viện của mình.
class CollectionConverter {
<T> List<T> toList(Collection<T> c) {...}
}
Bạn chưa sẵn sàng để thực hiện bất kỳ cập nhật nào, vì vậy bạn rời khỏi Overrider
lớp học của mình. Để ghi đè chính xác toList()
phương thức, các nhà thiết kế ngôn ngữ đã quyết định rằng một loại thô là "tương đương ghi đè" với bất kỳ loại tổng quát nào. Điều này có nghĩa là mặc dù chữ ký phương thức của bạn không còn chính thức bằng chữ ký của siêu lớp của tôi, phương thức của bạn vẫn ghi đè.
Bây giờ, thời gian trôi qua và bạn quyết định bạn đã sẵn sàng để cập nhật lớp học của mình. Nhưng bạn làm hỏng một chút và thay vì chỉnh sửa toList()
phương thức thô, hiện có , bạn thêm một phương thức mới như thế này:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
Do sự tương đương ghi đè của các loại thô, cả hai phương thức đều ở dạng hợp lệ để ghi đè toList(Collection<T>)
phương thức. Nhưng tất nhiên, trình biên dịch cần giải quyết một phương thức duy nhất. Để loại bỏ sự mơ hồ này, các lớp không được phép có nhiều phương thức tương đương với ghi đè, đó là nhiều phương thức có cùng loại tham số sau khi xóa.
Điều quan trọng là đây là một quy tắc ngôn ngữ được thiết kế để duy trì khả năng tương thích với mã cũ bằng cách sử dụng các loại thô. Nó không phải là một giới hạn theo yêu cầu của việc xóa các tham số loại; bởi vì độ phân giải phương thức xảy ra tại thời gian biên dịch, việc thêm các kiểu chung vào mã định danh phương thức sẽ là đủ.