2011-10-14 26 views
7

Tôi có yêu cầu kỳ lạ sau đây.Cách tạo bytecode và lưu vào tệp .class?

tôi đưa ra:

  1. Một danh sách một số tên phương pháp.
  2. Tên và loại thông số của các phương pháp trên.
  3. Chức năng của các phương pháp trên. Điều này như sau: Đối với mỗi tham số, phương thức chuyển đổi nó thành chuỗi bằng cách sử dụng toString và nhận được một chuỗi các chuỗi. Đối với mảng này, phương thức áp dụng một hàm foo. Hàm foo lấy làm đầu vào kiểu String [] và kết quả đầu ra String. Các phương thức trả về số tiền trả về foo. Mã số foo được đưa vào bên trong đối tượng Java và được truy cập dưới dạng hộp đen.

Thông tin trong 1. và 2. có thể ở dạng văn bản hoặc tệp XML. Với mục đích này, chúng ta có thể xem xét nó có sẵn bên trong một đối tượng Java theo bất kỳ cách nào chúng ta chọn.

Nhiệm vụ là tạo tệp .class (ví dụ: bytecode) triển khai các phương thức đó và có thể chạy trên JVM.

Tôi nghĩ rằng this assembler library sẽ là một cách để thực hiện điều đó. Bất cứ ai có thể đề xuất một cách dễ dàng hơn?

[EDIT:] Tôi có thể nghĩ ra một cách khác: đầu tiên tạo tệp .java và sau đó biên dịch tệp để nhận tệp .class.

[Bối cảnh:] Tôi phải thực hiện việc này cho hàng trăm phương pháp. Tôi muốn phím tắt để tôi có thể tự động hóa công việc của mình thay vì viết mã theo cách thủ công.

+0

Xin cho biết thêm ngữ cảnh, bạn muốn đạt được điều gì ... Lý do duy nhất tôi thấy để "tạo" các phương thức cụ thể cho một hành vi chung (foo) là an toàn kiểu hữu ích trong thời gian biên dịch ...Bạn sẽ sử dụng/gọi mã được tạo như thế nào? – pgras

+0

Tôi sẽ không gọi mã được tạo. Những gì tôi muốn làm là tạo một thư viện API (jar) cho ai đó sử dụng. Lớp sẽ có tên cụ thể, vì vậy họ sẽ biết API nào cần gọi. – Jus12

+0

OK Tôi thấy vấn đề với hàng trăm phương pháp, danh sách các phương pháp có thay đổi thường xuyên hay không? chúng ta có thể có một ví dụ về đầu vào bạn đang sử dụng không? – pgras

Trả lời

7

Bạn có thể tạo mã chương trình bắt buộc bằng cú pháp Java và biến nó thành tệp lớp bằng trình biên dịch. Có thể khởi tạo javac tại thời gian chạy và chuyển cho nó một mảng byte thay vì vị trí của tệp nguồn. Đây có lẽ là cách dễ nhất để các lập trình viên khác duy trì.

Nếu bạn muốn tạo mã byte trực tiếp, asm là thư viện được sử dụng phổ biến nhất.

+0

Tôi nghĩ đây có thể là cách thuận tiện nhất (tạo '.java'). – Jus12

+0

Bạn có thể cung cấp một số thông tin về cách thực hiện điều này thông qua 'javac' giả sử tôi đã tạo tệp .java không? – Jus12

+1

Nó nằm trong gói 'javax.tools'. Bài viết này có ví dụ: http://www.ibm.com/developerworks/java/library/j-jcomp/index.html. Tôi phải thừa nhận rằng tôi đã không tự sử dụng API 'javax.tools'. – Barend

1

tôi thấy bạn trả lời cho nhận xét của tôi, nhưng nó vẫn còn chưa rõ ràng đối với tôi lý do tại sao bạn muốn tạo mã sau đó được đóng gói trong một cái lọ, chỉ cần gõ nó :)

Bây giờ nếu bạn muốn có một typesafe api với tất cả các phương thức có hành vi giống nhau, bạn có thể cung cấp proxy động cho một giao diện cụ thể (điều này khiến bạn có câu hỏi về cách tạo giao diện :)

Đây là ví dụ nơi tất cả các cuộc gọi đến tất cả phương thức MyInterface sẽ được xử lý bằng phương thức gọi (chỉ cần thêm các phương thức vào giao diện để kiểm tra nó) ...

package test; 

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 

public class Test { 

interface MyInterface { 

    String methodOne(String s); 

    String methodTwo(String s, Integer i); 
} 

static MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
     MyInterface.class.getClassLoader(), 
     new Class[] { MyInterface.class }, new InvocationHandler() { 
      public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable { 
       StringBuilder result = new StringBuilder(); 
       for (Object arg : args) { 
        result.append(arg.toString()); 
       } 
       return result.toString(); 
      } 
     }); 

public static void main(String[] args) { 
    System.out.println(proxy.methodOne("hello"));  
    System.out.println(proxy.methodTwo("world", 5)); 

} 

} 
+0

Nếu tôi có thể nhập nhiều như vậy, sẽ không cần phải đặt câu hỏi :-). Tôi sử dụng Scala chủ yếu vì tôi không thích gõ. – Jus12

Các vấn đề liên quan