Tôi muốn thử chia nhỏ câu trả lời từ @DerMike để giải thích:
Đầu tiên, xóa kiểu không có nghĩa là JDK loại bỏ thông tin kiểu khi chạy. Đây là một phương pháp để cho phép kiểm tra kiểu thời gian biên dịch và khả năng tương thích kiểu thời gian chạy cùng tồn tại trong cùng một ngôn ngữ. Như khối mã này ngụ ý, JDK giữ lại thông tin loại đã xóa - nó chỉ không liên quan đến các phôi và nội dung được kiểm tra.
Thứ hai, điều này cung cấp thông tin loại chung cho một lớp chung chính xác một cấp độ gia truyền từ loại cụ thể được kiểm tra - tức là một lớp cha trừu tượng với các tham số loại chung có thể tìm thấy các loại cụ thể tương ứng với các tham số loại của nó để thực hiện cụ thể mà trực tiếp thừa hưởng từ nó. Nếu lớp này không trừu tượng và khởi tạo, hoặc việc triển khai cụ thể giảm hai cấp, thì điều này sẽ không hiệu quả (mặc dù một chút mánh lới có thể khiến nó áp dụng cho bất kỳ cấp độ nào được xác định trước vượt quá một hoặc đến cấp thấp nhất với các tham số loại X chung, et cetera).
Dù sao, để giải thích. Đây là mã một lần nữa, được tách thành các dòng để dễ tham khảo:
1 # Class genericParameter0Of ThisClass =
2 # (Lớp)
3 # ((ParameterizedType)
4 # getClass ()
5 # .getGenericSuperclass ())
6 # .getActualTypeArgument () [0];
Hãy 'chúng tôi' là lớp trừu tượng với các loại chung có chứa mã này. Đọc này đại khái từ trong ra ngoài:
- Dòng 4 lấy thể hiện Class của lớp cụ thể hiện tại. Điều này xác định loại bê tông con cháu ngay lập tức của chúng tôi.
- Dòng 5 lấy siêu kiểu của lớp đó là Loại; đây là chúng tôi. Vì chúng tôi là loại tham số, chúng tôi có thể tự chuyển mình thành ParameterizedType (dòng 3) một cách an toàn. Điều quan trọng là khi Java xác định đối tượng Loại này, nó sử dụng thông tin loại có trong phần tử con để liên kết thông tin loại với các tham số loại của chúng ta trong thể hiện ParameterizedType mới. Vì vậy, bây giờ chúng ta có thể truy cập các loại cụ thể cho thuốc generic của chúng tôi.
- Dòng 6 lấy mảng các kiểu được ánh xạ vào tổng quát của chúng tôi, theo thứ tự như được khai báo trong mã lớp. Đối với ví dụ này, chúng tôi rút ra tham số đầu tiên. Điều này trở lại như là một loại.
- Dòng 2 phôi Loại cuối cùng được trả về Lớp. Điều này an toàn vì chúng tôi biết loại tham số loại chung nào của chúng tôi có thể lấy và có thể xác nhận rằng tất cả chúng sẽ là các lớp (Tôi không chắc người Java sẽ đi bằng cách lấy tham số chung không có cá thể Class như thế nào liên kết với nó, thực sự).
... và đó là khá nhiều đó. Vì vậy, chúng tôi đẩy thông tin loại từ việc triển khai cụ thể của chúng tôi trở lại vào chính chúng tôi và sử dụng thông tin đó để truy cập vào một điều khiển lớp. chúng ta có thể tăng gấp đôi getGenericSuperclass () và đi hai cấp độ hoặc loại bỏ getGenericSuperclass () và nhận các giá trị cho bản thân dưới dạng cụ thể (báo trước: Tôi chưa thử các kịch bản này, chúng chưa đưa ra cho tôi).
Sẽ rất khó khăn nếu những đứa trẻ cụ thể của bạn là một số bước nhảy tùy ý, hoặc nếu bạn cụ thể và không phải là cuối cùng, và đặc biệt là khó khăn nếu bạn mong muốn bất kỳ đứa trẻ nào của bạn (sâu sắc) có thể có chung chung. Nhưng bạn thường có thể thiết kế xung quanh những cân nhắc đó, vì vậy điều này giúp bạn có được hầu hết các cách.
Hy vọng điều này đã giúp ai đó! Tôi nhận ra bài này là cổ xưa. Có lẽ tôi sẽ cắt lời giải thích này và giữ nó cho các câu hỏi khác.