Tôi đang viết một công cụ mã hóa Bytecode. Ngay bây giờ, tôi đang cố gắng tìm hiểu làm thế nào để làm điều đó trong sự hiện diện của các đối tượng. Tôi muốn một số giải thích về hai dòng tôi đọc trong JVMS (phần 4.9.4):Làm rõ trên Bytecode và các đối tượng
1) "Trình xác minh loại bỏ mã sử dụng đối tượng mới trước khi nó được khởi tạo".
Câu hỏi của tôi là, "sử dụng" có nghĩa là gì ở đây? Tôi đoán rằng điều đó có nghĩa là: chuyển nó thành thuộc tính phương thức, gọi số GETFIELD
và PUTFIELD
trên đó hoặc gọi bất kỳ phương thức thể hiện nào trên đó. Các ứng dụng bị cấm khác của họ? Và tôi tin rằng nó tuân theo các hướng dẫn khác như DUP
, LOAD
và STORE
được cho phép.
2) "Trước đây phương pháp đó gọi một phương pháp dụ khởi tạo của myClass hoặc lớp cha trực tiếp của nó trên này, hoạt động chỉ phương pháp có thể thực hiện về vấn đề này được gán lĩnh vực tuyên bố trong vòng myClass."
Có nghĩa là trong phương thức <init>
, GETFIELD và PUTFIELD được phép trước khi gọi <init>
khác. Tuy nhiên, trong Java, thực hiện bất kỳ thao tác nào trên một trường cá thể trước khi gọi tới số super()
hoặc this()
dẫn đến lỗi biên dịch. Ai đó có thể làm rõ điều này?
3) Tôi có thêm một câu hỏi. Khi nào một tham chiếu đối tượng được khởi tạo, và do đó, sẵn sàng để được sử dụng một cách tự do? Từ đọc các JVMS, tôi đã đưa ra câu trả lời cho dù một đối tượng được khởi tạo hay không, là tùy thuộc vào từng phương thức. Tại một thời điểm nhất định, đối tượng có thể được khởi tạo cho một phương thức nhưng không thể cho đối tượng kia. Cụ thể, một đối tượng được khởi tạo cho một phương thức khi <init>
gọi bằng phương thức đó trả về.
Ví dụ: xem xét phương thức main()
đã tạo đối tượng và được gọi là <init>
, sau đó được gọi là siêu lớp <init>
. Sau khi trở về từ super()
, đối tượng hiện được coi là được khởi tạo bởi <init>
, nhưng chưa được khởi tạo cho main()
. Điều này có nghĩa là, trong <init>
sau super()
, tôi có thể chuyển đối tượng dưới dạng tham số cho phương thức, ngay cả trước khi trở về từ chính().
Ai đó có thể xác nhận rằng toàn bộ phân tích này là đúng? Cảm ơn bạn đã dành thời gian.
ps: Tôi đã thực sự đăng câu hỏi tương tự lên diễn đàn Sun nhưng với phản hồi. Tôi hy vọng tôi sẽ có thêm may mắn ở đây. Cảm ơn bạn.
Cập nhật
Đầu tiên cảm ơn bạn đã trả lời và thời gian của bạn. Mặc dù tôi không nhận được câu trả lời rõ ràng (tôi có nhiều câu hỏi và một số câu hỏi mơ hồ), câu trả lời và ví dụ của bạn, và các thí nghiệm tiếp theo, cực kỳ hữu ích cho tôi để hiểu sâu hơn về cách JVM hoạt động.
Điều chính tôi phát hiện là hành vi của Trình xác minh khác với các triển khai và phiên bản khác nhau (làm cho công việc thao tác bytecode phức tạp hơn nhiều).Vấn đề nằm ở sự không phù hợp với các JVMS, hoặc thiếu tài liệu từ các nhà phát triển của trình xác minh, hoặc JVMS có một số vagueness tinh tế trong khu vực của người xác minh.
Một điều cuối cùng, SO Rocks !!! Tôi đã đăng cùng một câu hỏi trong diễn đàn Sun JVM Technical chính thức, và tôi vẫn chưa có câu trả lời cho đến bây giờ.
Nó không phải là một ý tưởng tồi, nhưng bạn nên cẩn thận với điều này . Trong quá khứ, trình xác minh thực tế được sử dụng ít nghiêm ngặt hơn về các quy tắc hơn so với đặc điểm kỹ thuật. Hoàn toàn có thể là những trường hợp như vậy vẫn xảy ra. –
Có, tôi phát hiện ra rằng các cách triển khai khác nhau của Trình xác minh có mức độ nghiêm ngặt khác nhau. Ví dụ, trình xác minh JustIce của Apache BCEL không cho phép STORE trên các tham chiếu đối tượng chưa được khởi tạo, trong khi Java HotSpot 10.0 thực hiện –