Nó có nghĩa là đối số kiểu cho enum phải xuất phát từ một enum mà chính nó có cùng đối số kiểu. Làm thế nào điều này có thể xảy ra? Bằng cách làm cho đối số kiểu chính nó. Vì vậy, nếu tôi có một enum được gọi là StatusCode, nó sẽ tương đương với:
public class StatusCode extends Enum<StatusCode>
Bây giờ nếu bạn kiểm tra các ràng buộc, chúng tôi đã có Enum<StatusCode>
- vì vậy E=StatusCode
. Hãy kiểm tra: có E
mở rộng Enum<StatusCode>
không? Đúng! Chúng tôi ổn.
Bạn cũng có thể tự hỏi ý nghĩa của vấn đề này là gì :) Vâng, điều đó có nghĩa là API cho Enum có thể tự tham chiếu - ví dụ, có thể nói rằng Enum<E>
thực hiện điều đó Comparable<E>
. Lớp cơ sở có thể thực hiện các phép so sánh (trong trường hợp enum) nhưng nó có thể đảm bảo rằng nó chỉ so sánh đúng loại enum với nhau. (EDIT: Chà, gần như - xem phần chỉnh sửa ở phía dưới.)
Tôi đã sử dụng một cái gì đó tương tự trong cổng C # của ProtocolBuffers. Có "thông điệp" (không thay đổi) và "người xây dựng" (có thể thay đổi, được sử dụng để xây dựng một thông điệp) - và chúng có dạng cặp. Các giao diện liên quan là:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
Điều này có nghĩa là từ một tin nhắn, bạn có thể có được một nhà xây dựng thích hợp (ví dụ: lấy một bản sao của tin nhắn và thay đổi một số bit) và từ một nhà xây dựng, bạn có thể nhận được một tin nhắn phù hợp khi bạn xây dựng xong nó. Đó là một công việc tốt mà người dùng API không cần thực sự quan tâm về vấn đề này - nó phức tạp khủng khiếp và đã thực hiện một số lần lặp để đến nơi.
EDIT: Lưu ý rằng điều này không ngăn bạn tạo các loại lẻ sử dụng đối số loại mà bản thân nó ổn, nhưng không phải là cùng loại. Mục đích là để cho lợi ích trong đúng trường hợp chứ không phải là bảo vệ bạn khỏi những sai trường hợp.
Vì vậy, nếu Enum
không được xử lý "đặc biệt" trong Java, bạn có thể (như đã lưu ý trong các nhận xét) tạo các loại sau:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
sẽ thực hiện Comparable<First>
chứ không phải Comparable<Second>
... nhưng First
bản thân nó sẽ ổn thôi.