Tôi nhận thức rõ rằng các kiểu chung được xóa khỏi mã Java khi được biên dịch. Thông tin (thuộc tính nào) làm 1,5+ JVM sử dụng để triển khai getGenericType
, v.v ...?Các loại chung được lưu trữ trong các tệp lớp java ở đâu?
Trả lời
Chúng được lưu trữ trong các thuộc tính Signature
; xem phần 4.8.8 của updated Java Virtual Machine Specification, cũng như phần 4.4.4 cho định dạng chữ ký loại trường.
Dưới đây là một ví dụ sử dụng javap -verbose java.util.Map
:
public interface java.util.Map
SourceFile: "Map.java"
Signature: length = 0x2
00 1E
[other attributes omitted]
Các Signature
thuộc tính ở đây quy định cụ thể (nếu bạn đọc này như lớn về cuối nhỏ, giống như tất cả số lượng số nguyên trong các định dạng tập tin lớp JVM là) hồ bơi liên tục giá trị # 30 (30 = 0x1E).Vì vậy, chúng ta hãy có một cái nhìn ở đó:
const #30 = Asciz <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;;
Đọc điều này trong ngữ cảnh được quy định trong 4.4.4. Vì vậy, điều này sử dụng hai thông số loại, K extends java.lang.Object
và V extends java.lang.Object
. Bản thân loại (Map
) cũng mở rộng lớp java.lang.Object
và không có giao diện.
Generics Java thực sự được thực hiện bởi type erasure, vì vậy không có thông tin loại nào trong bytecode.
Ví dụ, chúng ta hãy xem xét hai lớp đó khai báo một lĩnh vực List
, một ở chung và người kia ở dạng phi-generic:
class NonGeneric {
List list;
}
Và,
class Generic {
List<String> list;
}
Trong cả hai trường hợp , bytecode kết quả như sau:
Code:
Stack=3, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: new #2; //class java/util/ArrayList
8: dup
9: invokespecial #3; //Method java/util/ArrayList."<init>":()V
12: putfield #4; //Field list:Ljava/util/List;
15: return
Không có giới thiệu ce đến loại String
được sử dụng trong ArrayList
cũng không phải List
. Vì vậy, chúng ta có thể thấy rằng generics thực sự được thực hiện bởi loại erasure.
Tuy nhiên, nếu chúng ta nhìn vào hồ bơi không đổi, chúng ta có thể tìm thấy sự khác biệt.
phi-generic hồ bơi liên tục:
Constant pool:
const #1 = Method #6.#15; // java/lang/Object."<init>":()V
const #2 = class #16; // java/util/ArrayList
const #3 = Method #2.#15; // java/util/ArrayList."<init>":()V
const #4 = Field #5.#17; // NonGeneric.list:Ljava/util/List;
const #5 = class #18; // NonGeneric
const #6 = class #19; // java/lang/Object
const #7 = Asciz list;
const #8 = Asciz Ljava/util/List;;
const #9 = Asciz <init>;
const #10 = Asciz ()V;
// snip the rest //
Các generic hồ bơi liên tục:
Constant pool:
const #1 = Method #6.#17; // java/lang/Object."<init>":()V
const #2 = class #18; // java/util/ArrayList
const #3 = Method #2.#17; // java/util/ArrayList."<init>":()V
const #4 = Field #5.#19; // Generic.list:Ljava/util/List;
const #5 = class #20; // Generic
const #6 = class #21; // java/lang/Object
const #7 = Asciz list;
const #8 = Asciz Ljava/util/List;;
const #9 = Asciz Signature;
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
const #11 = Asciz <init>;
const #12 = Asciz ()V;
// snip the rest//
Như có thể thấy, trong lớp Generic
, chúng ta có thể thấy có hai hằng số phụ, #9
và #10
, trong hồ bơi không đổi, đề cập đến rằng List
có loại chung là String
.
(Và kết hợp với kiến thức mới mà tôi học được từ Chris Jester-Young's answer)
Nhìn xa hơn vào tháo dỡ của tập tin lớp học, có một tham chiếu đến hằng số # 10 ngay trước khi Code: block
của lớp Generic
:
java.util.List list;
Signature: length = 0x2
00 0A
giá trị thập lục phân 0A
là 10
trong hệ thập phân, trong đó đề cập đến hồ bơi liên tục #10
:
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
Do đó, thông tin từ nhóm không đổi được sử dụng để cho biết rằng một trường là một kiểu chung.
- 1. Các lớp java được lưu trữ trong Oracle ở đâu?
- 2. Các tệp jar được lưu trữ ở đâu trong các ứng dụng Java Web Start/JNLP?
- 3. Các loại giá trị được lưu trữ ở đâu (C#) Bộ sưu tập chung
- 4. Các tệp evtx được lưu trữ ở đâu được lưu trữ?
- 5. CLR lưu trữ các lớp tĩnh ở đâu?
- 6. Các biến trong Python được lưu trữ ở đâu?
- 7. UIWebView lưu trữ các tệp ngoại tuyến HTML5 ở đâu?
- 8. Outlook lưu trữ các tệp mã VBA ở đâu?
- 9. Các khối CMS tĩnh Magento được lưu trữ ở đâu?
- 10. ".NET Storage" được lưu trữ ở đâu?
- 11. Lưu trữ tệp nhật ký lưu trữ ở đâu?
- 12. Các giao dịch mua InAPP được lưu trữ ở đâu?
- 13. Git lưu trữ tệp ở đâu?
- 14. Android: các tệp tải xuống được lưu ở đâu?
- 15. WordPress lưu trữ các trang HTML ở đâu?
- 16. Tệp Rails này được lưu trữ ở đâu? db/development.sqlite3
- 17. Các tùy chọn Java được lưu trữ trong Windows 7 ở đâu?
- 18. plugin maven được lưu trữ ở đâu
- 19. Các gói SSIS được lưu ở đâu?
- 20. Bạn lưu trữ các biến trong jinja ở đâu?
- 21. TempData được lưu trữ ở đâu?
- 22. ViewState được lưu trữ ở đâu?
- 23. Phương thức được lưu trữ trong bộ nhớ ở đâu?
- 24. Các tùy chọn Java được lưu trữ trên Mac OS X ở đâu?
- 25. Vars được lưu trữ ở đâu trong Nodej?
- 26. Các tệp dự án của tôi được lưu trữ ở đâu
- 27. Dấu trang Eclipse được lưu trữ ở đâu?
- 28. Các tệp lưu trữ trên Railo được tạo bởi <cflog> ở đâu?
- 29. Các tệp JSP Java (* __ jsp.java) được biên dịch ở đâu?
- 30. Các tệp kết xuất lõi được lưu trữ trên iPhone ở đâu?