Động lực học lập trình Java, Phần 7: Kỹ thuật bytecode với BCEL Apache BCEL cho phép bạn đi đến các chi tiết về ngôn ngữ assembler của JVM cho hoạt động lớp doc

24 359 0
Động lực học lập trình Java, Phần 7: Kỹ thuật bytecode với BCEL Apache BCEL cho phép bạn đi đến các chi tiết về ngôn ngữ assembler của JVM cho hoạt động lớp doc

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Động lực học lập trình Java, Phần 7: Kỹ thuật bytecode với BCEL Apache BCEL cho phép bạn đi đến các chi tiết về ngôn ngữ assembler của JVM cho hoạt động lớp Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc. Tóm tắt: Apache Byte Code Engineering Library (BCEL-Thư viện kỹ thuật mã byte) cho phép bạn nghiên cứu bytecode của các lớp Java. Bạn có thể sử dụng nó để biến đổi các biểu diễn lớp hiện tại hoặc xây dựng các lớp mới, và vì BCEL làm việc ở mức các lệnh JVM riêng biệt, nó sẽ cho bạn sức mạnh tối đa trên mã của bạn. Mặc dù sức mạnh đó đi kèm với một chi phí về độ phức tạp. Trong bài này, nhà tư vấn Java Dennis Sosnoski cung cấp cho bạn những điều cơ bản về BCEL và hướng dẫn bạn thông qua một ví dụ ứng dụng BCEL để cho bạn có thể tự quyết định xem sức mạnh có tương xứng với sự phức tạp không. Trong ba bài viết mới đây của loạt bài này, tôi đã cho bạn thấy cách sử dụng khung công tác Javassist cho hoạt động lớp (classworking). Bây giờ tôi sẽ trình bày một cách tiếp cận rất khác để xử lí bytecode, đó là sử dụng Apache Byte Code Engineering Library (BCEL). BCEL hoạt động ở mức các lệnh JVM thực sự, không giống như giao diện mã nguồn được Javassist hỗ trợ. Cách tiếp cận mức thấp làm cho BCEL rất tốt khi bạn thực sự muốn kiểm soát mọi bước thực hiện chương trình, nhưng nó cũng làm cho hoạt động với BCEL phức tạp hơn nhiều so với sử dụng Javassist cho các trường hợp ở đó cả hai cùng làm việc. Tôi sẽ bắt đầu bằng cách trình bày kiến trúc BCEL cơ bản, sau đó dành hầu hết bài viết này cho việc xây dựng lại ví dụ hoạt động lớp Javassist đầu tiên của tôi bằng BCEL. Tôi sẽ kết thúc bằng việc xem xét một số các công cụ có trong gói BCEL và một vài ứng dụng mà các nhà phát triển đã xây dựng ở trên BCEL. Truy cập lớp BCEL BCEL cung cấp cho bạn tất cả các khả năng cơ bản giống như Javassist kiểm tra, chỉnh sửa và tạo các lớp Java nhị phân. Sự khác biệt rõ ràng với BCEL là mọi thứ được thiết kế để làm việc ở mức ngôn ngữ chương trình dịch hợp ngữ (assembler) của JVM, hơn là giao diện mã nguồn do Javassist cung cấp. Có một số khác biệt sâu hơn dưới các vỏ bọc, gồm việc sử dụng hai hệ thống phân cấp riêng của các thành phần trong BCEL một cái kiểm tra mã hiện có và cái khác để tạo mã mới. Tôi sẽ giả định bạn quen với Javassist từ những bài viết trước trong loạt bài này (xem phần bên cạnh Đừng bỏ lỡ phần còn lại của loạt bài này). Vì vậy tôi sẽ tập trung vào những sự khác biệt có khả năng gây nhầm lẫn cho bạn khi bạn bắt đầu làm việc với BCEL. Như với Javassist, các khía cạnh kiểm tra lớp của BCEL về cơ bản lặp lại những gì có sẵn trực tiếp trong nền tảng Java qua Reflection API. Điều trùng lắp này là cần thiết trong một bộ công cụ hoạt động lớp vì bạn thường không muốn nạp các lớp mà bạn đang làm việc với chúng cho đến sau khi chúng đã được thay đổi. Đừng bỏ lỡ phần còn lại của loạt bài này Phần 1, "Các lớp Java và nạp lớp" (04.2003) Phần 2, "Giới thiệu sự phản chiếu" (06.2003) Phần 3, "Ứng dụng sự phản chiếu" (07.2003) Phần 4, "Chuyển đổi lớp bằng Javassist" (09.2003) Phần 5, "Việc chuyển các lớp đang hoạt động" (02.2004) Phần 6, "Các thay đổi hướng-khía cạnh với Javassist" (03.2004) Phần 8, "Thay thế sự phản chiếu bằng việc tạo mã" (06.2004) BCEL cung cấp một số định nghĩa không thay đổi cơ bản trong gói org.apache.bcel, nhưng không kể những định nghĩa này, tất cả các mã kiểm tra có liên quan nằm trong gói org.apache.bcel.classfile. Điểm khởi đầu trong gói này là lớp JavaClass. Lớp này đóng vai trò giống như trong việc truy cập thông tin lớp bằng cách sử dụng BCEL như lớp java.lang.Class thực hiện khi dùng sự phản chiếu của Java chuẩn. JavaClass xác định các phương thức để nhận được thông tin trường và phương thức cho lớp này, cũng như thông tin theo cấu trúc về siêu lớp và các giao diện. Không giống như java.lang.Class, JavaClass cũng cung cấp quyền truy cập tới các thông tin nội bộ cho lớp đó, gồm nhóm hằng số và các thuộc tính và biểu diễn lớp nhị phân đầy đủ như một luồng byte. Các cá thể JavaClass thường được tạo bằng cách phân tích cú pháp lớp nhị phân hiện có. BCEL cung cấp lớp org.apache.bcel.Repositoryđể thực hiện phân tích cú pháp cho bạn. Theo mặc định, BCEL phân tích cú pháp và lưu trữ nhanh các biểu diễn của các lớp được tìm thấy trong đường dẫn lớp (classpath) JVM, nhận được các biểu diễn lớp nhị phân thực sự từ một cá thể org.apache.bcel.util.Repository (lưu ý sự khác biệt trong tên gói). Hiện tại org.apache.bcel.util.Repository là một giao diện cho một nguồn biểu diễn lớp nhị phân. Bạn có thể thay thế các đường dẫn khác để tìm kiếm các tệp lớp hoặc các cách truy cập thông tin lớp khác, thay cho nguồn mặc định có sử dụng đường dẫn lớp. Thay đổi các lớp Bên cạnh việc truy cập kiểu-phản chiếu tới các thành phần lớp, org.apache.bcel.classfile.JavaClass cũng cung cấp các phương thức để thay đổi lớp đó. Bạn có thể sử dụng những phương thức này để thiết lập bất kỳ các thành phần lớp này với các giá trị mới. Mặc dù, chúng thường không sử dụng trực tiếp, vì các lớp khác trong gói đó không hỗ trợ cho việc xây dựng các phiên bản mới của các thành phần theo bất kỳ cách hợp lý nào. Thay vào đó, có một tập riêng biệt đầy đủ các lớp trong gói org.apache.bcel.generic để cung cấp phiên bản có thể chỉnh sửa được của các thành phần được các lớp org.apache.bcel.classfile biểu diễn. Cũng như org.apache.bcel.classfile.JavaClass là điểm khởi đầu cho việc sử dụng BCEL để kiểm tra các lớp hiện có, org.apache.bcel.generic.ClassGen là điểm bắt đầu của bạn để tạo các lớp mới. Nó cũng thay đổi các lớp hiện tại để xử lý trường hợp đó, có một hàm tạo lấy một cá thể JavaClass và sử dụng nó để khởi tạo thông tin lớp ClassGen. Một khi bạn đã hoàn tất các thay đổi lớp của bạn, bạn có thể nhận được một sự biểu diễn lớp thích hợp từ cá thể ClassGen bằng cách gọi một phương thức trả về một JavaClass, nó có thể lần lượt được chuyển đổi sang biểu diễn lớp nhị phân. Hỏi chuyên gia: Dennis Sosnoski về các vấn đề JVM và bytecode Đối với các ý kiến hay các câu hỏi về tài liệu được trình bày trong loạt bài này, cũng như bất cứ điều gì khác có liên quan đến Java bytecode, định dạng lớp nhị phân Java hoặc các vấn đề JVM chung, hãy truy cập vào diễn đàn thảo luận JVM và Bytecode, do Dennis Sosnoski kiểm soát. Nói lộn xộn quá phải không? Tôi nghĩ như vậy. Trong thực tế, việc quay lại và tiến lên giữa hai gói này là một trong những khía cạnh làm việc bất tiện nhất với BCEL. Các cấu trúc lớp sao chép lại hướng theo cách này, vì thế nếu bạn đang làm việc với BCEL, thật bõ công để viết các lớp của trình bao bọc (wrapper), mà nó có thể ẩn dấu một số các sự khác nhau này. Với bài viết này, tôi sẽ chủ yếu làm việc với các lớp của gói org.apache.bcel.generic và tránh sử dụng các trình bao bọc, nhưng với bạn đây là một điều để ghi nhớ cho công việc riêng của mình. Ngoài ClassGen, gói org.apache.bcel.generic định nghĩa các lớp để quản lý việc xây dựng các thành phần lớp khác nhau. Các lớp xây dựng này gồm ConstantPoolGen để xử lý nhóm hằng số FieldGen và MethodGen cho các trường và các phương thức và InstructionList để làm việc với các chuỗi của các lệnh JVM. Cuối cùng, gói org.apache.bcel.generic cũng định nghĩa các lớp để biểu diễn mọi kiểu của các lệnh JVM. Bạn có thể trực tiếp tạo các cá thể của các lớp này hoặc trong một số trường hợp bằng cách sử dụng lớp của trình trợ giúp (helper) org.apache.bcel.generic.InstructionFactory. Lợi thế của việc sử dụng InstructionFactory là nó xử lý các chi tiết tạo sổ sách của việc xây dựng lệnh cho bạn (gồm cả việc thêm các mục vào nhóm hằng số khi cần thiết cho các lệnh). Bạn sẽ thấy cách làm cho tất cả các lớp này hoạt động cùng nhau trong phần tiếp theo. Hoạt động lớp với BCEL Đối với một ví dụ về việc áp dụng BCEL, tôi sẽ sử dụng cùng một nhiệm vụ mà tôi đã sử dụng như một ví dụ Javassist trong Phần 4 việc đo thời gian được dùng để thực hiện một phương thức. Tôi thậm chí sẽ sử dụng cùng một cách tiếp cận mà tôi đã sử dụng với Javassist: tôi sẽ tạo một bản sao của phương thức ban đầu có tính thời gian khi sử dụng một tên đã thay đổi, sau đó thay thế phần thân của phương thức ban đầu với mã bao bọc các tính toán đếm thời gian xung quanh một cuộc gọi đến phương thức đã đổi tên. Chọn một vật thí nghiệm Liệt kê 1 đưa ra một phương thức ví dụ mà tôi sẽ sử dụng cho các mục đích giải thích: phương thức buildString của lớp StringBuilder. Như tôi đã nói trong Phần 4, phương thức này xây dựng một String có độ dài yêu cầu bất kỳ bằng cách thực hiện chính xác những gì mà bất kỳ chuyên gia hiệu năng Java nào khuyên bạn không nên làm nó liên tục gắn thêm một ký tự vào cuối của một chuỗi để tạo một chuỗi dài hơn. Vì các chuỗi không thay đổi được, nên cách tiếp cận này có nghĩa là một chuỗi mới sẽ được xây dựng mỗi khi qua vòng lặp, với các dữ liệu được sao chép từ chuỗi cũ và một ký tự được thêm vào cuối. Ảnh hưởng cuối cùng là phương thức này phải chịu chi phí hoạt động càng ngày càng nhiều khi nó được sử dụng để tạo các chuỗi dài hơn. Liệt kê 1. Phương thức có tính giờ public class StringBuilder { private String buildString(int length) { String result = ""; for (int i = 0; i < length; i++) { result += (char)(i%26 + 'a'); } return result; } public static void main(String[] argv) { StringBuilder inst = new StringBuilder(); for (int i = 0; i < argv.length; i++) { String result = inst.buildString(Integer.parseInt(argv[i])); System.out.println("Constructed string of length " + result.length()); } } } Liệt kê 2 cho thấy mã nguồn tương đương với sự thay đổi hoạt động lớp mà tôi sẽ làm với BCEL. Ở đây phương thức của trình bao bọc (wrapper) chỉ lưu trữ thời gian hiện tại, sau đó gọi phương thức ban đầu đã đổi tên và in ra một thông báo thời gian trước khi trả về kết quả của cuộc gọi đến phương thức ban đầu. Liệt kê 2. Tính thời gian đã thêm vào phương thức ban đầu public class StringBuilder { private String buildString$impl(int length) { String result = ""; for (int i = 0; i < length; i++) { result += (char)(i%26 + 'a'); } return result; } private String buildString(int length) { long start = System.currentTimeMillis(); String result = buildString$impl(length); System.out.println("Call to buildString$impl took " + (System.currentTimeMillis()-start) + " ms."); return result; } public static void main(String[] argv) { StringBuilder inst = new StringBuilder(); for (int i = 0; i < argv.length; i++) { String result = inst.buildString(Integer.parseInt(argv[i])); System.out.println("Constructed string of length " + result.length()); } } } Mã hóa phép chuyển đổi Triển khai thực hiện mã để thêm việc tính thời gian phương thức sử dụng các BCEL API mà tôi đã nêu ra trong phần Truy cập lớp BCEL. Làm việc ở mức các lệnh JVM làm cho đoạn mã dài hơn rất nhiều so với ví dụ Javassist trong Phần 4, do đó ở đây tôi sẽ duyệt qua nó từng đoạn một trước khi cung cấp cho bạn việc thực hiện đầy đủ. Trong đoạn mã cuối cùng, tất cả các đoạn này sẽ tạo nên chỉ một phương thức, một phương thức lấy một cặp tham số: cgen, một cá thể của lớp org.apache.bcel.generic.ClassGen được khởi tạo bằng các thông tin hiện có cho các lớp đang được thay đổi; và method (phương thức), một cá thể org.apache.bcel.classfile.Method cho phương thức tôi sắp tính thời gian. Liệt kê 3 có đoạn mã đầu tiên cho phương thức chuyển đổi. Như bạn thấy từ các ý kiến, phần đầu tiên chỉ khởi tạo các thành phần BCEL cơ bản mà tôi sắp sử dụng, gồm việc khởi tạo một cá thể org.apache.bcel.generic.MethodGen mới bằng cách sử dụng các thông tin cho phương thức có tính giờ. Tôi thiết lập một danh sách lệnh rỗng cho MethodGen, để sau này tôi sẽ điền vào đó với mã tính thời gian thực tế. Trong phần thứ hai, tôi tạo một cá thể org.apache.bcel.generic.MethodGen thứ hai từ phương thức ban đầu, sau đó loại bỏ phương thức ban đầu khỏi lớp đó. Trong cá thể MethodGen thứ hai này, tôi chỉ cần thay đổi tên để sử dụng một hậu tố "$impl", sau đó gọi phương thức getMethod() để chuyển đổi thông tin phương thức có thể thay đổi được thành một dạng cố định như một cá thể org.apache.bcel.classfile.Method. Sau đó tôi sử dụng cuộc gọi addMethod() để thêm phương thức đã đổi tên vào lớp đó. Liệt kê 3. Thêm phương thức chặn // set up the construction tools InstructionFactory ifact = new InstructionFactory(cgen); InstructionList ilist = new InstructionList(); ConstantPoolGen pgen = cgen.getConstantPool(); String cname = cgen.getClassName(); MethodGen wrapgen = new MethodGen(method, cname, pgen); wrapgen.setInstructionList(ilist); // rename a copy of the original method MethodGen methgen = new MethodGen(method, cname, pgen); cgen.removeMethod(method); String iname = methgen.getName() + "$impl"; methgen.setName(iname); cgen.addMethod(methgen.getMethod()); Liệt kê 4 cung cấp các đoạn mã tiếp theo cho phương thức chuyển đổi. Ở đây phần đầu tiên tính không gian bị chiếm bởi các tham số gọi phương thức trên ngăn xếp. Vì đoạn này cần thiết để lưu trữ thời gian bắt đầu trên khung ngăn xếp trước khi gọi phương thức bao bọc mà tôi cần phải biết có thể sử dụng khoảng trống nào cho một biến cục bộ (lưu ý rằng tôi có thể sử dụng việc xử lý biến cục bộ của BCEL để nhận được cùng tác dụng, nhưng với bài viết này tôi thích một cách tiếp cận rõ ràng). Phần thứ hai của đoạn mã này tạo cuộc gọi đến java.lang.System.currentTimeMillis() để nhận được thời gian bắt đầu, lưu nó vào khoảng trống của biến cục bộ đã được tính toán trong khung ngăn xếp. Có lẽ bạn tự hỏi tại sao tôi kiểm tra xem phương thức đó có tĩnh hay không ở lúc bắt đầu tính toán kích thước tham số của tôi, sau đó khởi tạo khe hở khung ngăn xếp là 0 nếu nó có (trái ngược với một khe hở nếu nó không có). Cách tiếp cận này liên quan đến cách xử lý các cuộc gọi phương thức ngôn ngữ Java. Đối với các phương thức không tĩnh, tham số (ẩn) đầu tiên trên mỗi cuộc gọi là tham chiếu này cho đối tượng đích, mà tôi cần phải tính đến khi tính toán kích thước tập tham số đầy đủ trên khung ngăn xếp. Liệt kê 4. Thiết lập cho cuộc gọi được bao bọc // compute the size of the calling parameters Type[] types = methgen.getArgumentTypes(); int slot = methgen.isStatic() ? 0 : 1; for (int i = 0; i < types.length; i++) { slot += types[i].getSize(); } // save time prior to invocation ilist.append(ifact.createInvoke("java.lang.System", "currentTimeMillis", Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC)); ilist.append(InstructionFactory.createStore(Type.LONG, slot)); Liệt kê 5 cho thấy đoạn mã để tạo cuộc gọi đến phương thức được bao bọc và lưu kết quả (nếu có). Phần đầu tiên của đoạn mã này sẽ kiểm tra xem phương thức này có tĩnh không. Nếu phương thức không tĩnh, tôi tạo mã để nạp tài liệu tham khảo đối tượng này cho ngăn xếp đó và cũng có thể thiết lập kiểu gọi phương thức là ảo (virtual) (chứ không phải tĩnh (static)). Vòng lặp for sau đó tạo mã để sao chép tất cả các giá trị tham số cuộc gọi tới ngăn xếp đó, phương thức createInvoke() tạo cuộc gọi thực sự tới phương thức được bao bọc và câu lệnh ifcuối cùng sẽ lưu giá trị kết quả đến vị trí biến cục bộ khác trong khung ngăn xếp (nếu kiểu kết quả không phải là rỗng ). Liệt kê 5. Gọi phương thức được bao bọc // call the wrapped method int offset = 0; short invoke = Constants.INVOKESTATIC; if (!methgen.isStatic()) { ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0)); offset = 1; invoke = Constants.INVOKEVIRTUAL; } for (int i = 0; i < types.length; i++) { Type type = types[i]; ilist.append(InstructionFactory.createLoad(type, offset)); offset += type.getSize(); } Type result = methgen.getReturnType(); [...]... dẫn đúng sự thực để phổ biến của BCEL Những lợi thế lớn của BCEL là giấy phép Apache tiện lợi cho thương mại của nó và sự hỗ trợ mức lệnh JVM rộng rãi của nó Các tính năng này, kết hợp với sự ổn định và tuổi thọ của nó, đã làm cho BCEL trở thành một sự lựa chọn rất phổ biến cho các ứng dụng hoạt động lớp Nhưng BCEL dường như không phải là tất cả được thiết kế tốt cho cả về tốc độ lẫn tính dễ sử dụng... dụng cả hai BCEL và Javassist để thay thế các cuộc gọi sự phản chi u với mã được tạo ra động trong thời gian chạy với một sự cải tiến đáng kể về hiệu năng Xem tiếp bài tháng tới về một trải nghiệm khác của Động lực học lập trình Java để tìm hiểu các chi tiết Mục lục  Truy cập lớp BCEL  Hoạt động lớp với BCEL  Tóm tắt BCEL  Phần tiếp theo ... và BCEL, bài viết tiếp theo của tôi trong loạt bài này sẽ nghiên cứu một ứng dụng hầu như có ích về hoạt động lớp nhiều hơn những gì bạn đã nhìn thấy cho đến nay Quay lại Phần 2, tôi đã giải thích sự phản chi u gọi đến các phương thức chậm hơn nhiều so với các cuộc gọi trực tiếp như thế nào Trong Phần 8, tôi sẽ chỉ ra cách bạn có thể sử dụng cả hai BCEL và Javassist để thay thế các cuộc gọi sự phản chi u... một trình tạo chương trình BCEL cung cấp mã nguồn cho một chương trình BCEL để xây dựng một lớp do bạn cung cấp (Lớp org .apache .bcel. util.BCELifier không nằm trong Javadocs, do đó hãy trông cậy vào mã nguồn với cách sử dụng Tính năng này hấp dẫn, nhưng kết quả có thể quá khó hiểu để dùng cho hầu hết các nhà phát triển) Theo cách sử dụng BCEL riêng của mình, tôi đã phát hiện thấy trình phân tách HTML... tắt BCEL Có nhiều thứ với BCEL hơn chỉ là sự hỗ trợ hoạt động lớp cơ bản mà tôi đã thể hiện trong bài viết này Nó cũng gồm việc thực hiện trình kiểm tra đầy đủ để đảm bảo rằng một lớp nhị phân là hợp lệ theo các đặc tả JVM (xem org .apache .bcel. verifier.VerifierFactory), một trình phân tách (disassembler) tạo một khung nhìn mức JVM được liên kết và có bố cục đẹp của một lớp nhị phân và thậm chí một trình. .. công tác được sử dụng rộng rãi nhất cho hoạt động lớp Java Nó liệt kê một số dự án khác có sử dụng BCEL trên trang Web, gồm trình biên dịch Xalan XSLT, mở rộng AspectJ cho ngôn ngữ lập trình Java và triển khai thực hiện một số JDO Nhiều dự án khác chưa được liệt kê cũng đang sử dụng BCEL, gồm dự án liên kết dữ liệu JiBX XML riêng của tôi Tuy nhiên, một số các dự án được BCEL liệt kê từ đó đã chuyển sang... lớp org .apache .bcel. util.Class2HTML với đường dẫn đến tệp lớp mà bạn muốn tách ra như một đối số dòng lệnh Nó sẽ tạo các tệp HTML trong thư mục hiện tại Ví dụ ở đây tôi sẽ phân tách lớp StringBuilder mà tôi đã sử dụng cho ví dụ tính thời gian của tôi: [dennis]$ java -cp bcel. jar org .apache .bcel. util.Class2HTML StringBuilder.class Processing StringBuilder.class Done Hình 1 là một ảnh chụp màn hình của. .. công việc để lại cho Liệt kê 7 là hoàn thành mã phương thức của trình bao bọc (wrapper) với một sự trả về giá trị kết quả đã lưu trữ (nếu có) từ cuộc gọi phương thức được bao bọc, tiếp theo là hoàn thành phương thức của trình bao bọc đã được xây dựng Phần cuối cùng này liên quan đến một vài bước Cuộc gọi đến stripAttributes(true) chỉ ra lệnh cho BCEL không tạo các thông tin gỡ rối cho phương thức được... System.out.println ("Usage: BCELTiming class-file method-name"); } } } Thực hiện một lượt Liệt kê 9 cho thấy các kết quả của lần đầu tiên chạy chương trình StringBuilder ở dạng chưa thay đổi, sau đó chạy chương trình BCELTiming để thêm thông tin về thời gian và cuối cùng là chạy chương trình StringBuilder sau khi nó đã thay đổi Bạn có thể thấy cách StringBuilder bắt đầu thông báo các thời gian thực hiện... đối với hầu hết các mục đích, với tốc độ tương đương (hoặc thậm chí tốt hơn), ít nhất là trong các thử nghiệm đơn giản của tôi Nếu dự án của bạn có thể tận dụng phần mềm có sử dụng Mozilla Public License (MPL) hoặc GNU Lesser General Public License (LGPL), thì Javassist có thể là một lựa chọn tốt hơn ngay bây giờ (nó có sẵn trong cả hai giấy phép này) Phần tiếp theo Bây giờ tôi đã giới thiệu cho bạn . Động lực học lập trình Java, Phần 7: Kỹ thuật bytecode với BCEL Apache BCEL cho phép bạn đi đến các chi tiết về ngôn ngữ assembler của JVM cho hoạt động lớp Dennis Sosnoski,. xử lý các chi tiết tạo sổ sách của việc xây dựng lệnh cho bạn (gồm cả việc thêm các mục vào nhóm hằng số khi cần thiết cho các lệnh). Bạn sẽ thấy cách làm cho tất cả các lớp này hoạt động cùng. được của các thành phần được các lớp org .apache .bcel. classfile biểu diễn. Cũng như org .apache .bcel. classfile.JavaClass là đi m khởi đầu cho việc sử dụng BCEL để kiểm tra các lớp hiện có, org .apache .bcel. generic.ClassGen

Ngày đăng: 07/08/2014, 10:22

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan