2010-07-14 28 views
12

Xác định getters và setters đơn giản dễ sử dụng Asm (và may mắn là nó được giải thích trong phần FAQ). Nhưng một điều không được đề cập, và tôi không thể tìm thấy tài liệu, là làm thế nào để thực hiện chúng bằng cách sử dụng thông tin kiểu chung chung.Tạo các phương thức với các kiểu generic với bộ tạo mã bytecode Asm (ClassWriter)

Tôi thực sự có thể tự xác định thông tin loại chung chung (vì mã sẽ lấy các trường và/hoặc phương thức hiện có và xử lý và giải quyết kiểu chung hoàn chỉnh). Tôi chỉ cần tạo ra phiên bản generics cho các loại có loại generic bao gồm.

Tôi hy vọng điều này dễ dàng như sửa đổi chữ ký Asm ClassWriter/MethodVisitor gọi, nhưng một số ý kiến ​​trong tài liệu cho thấy nó có thể không được dễ dàng (như thông tin generics được lưu trữ ở nơi bit khác với thông tin thường xuyên).

EDIT: có vẻ như điểm vào là "ClassWriter.visitField/Method (...., Chữ ký chuỗi) - lưu ý rằng đó là" mô tả "có chứa thông tin lớp chung không bình thường, nhưng cụm từ" chữ ký "

Trả lời

8

Bạn có thể tạo chữ ký bằng cách sử dụng lớp SignatureWriter của ASM

Ví dụ, giả sử bạn muốn viết chữ ký cho phương pháp này:

public <K> void doSomething(K thing) 

Bạn có thể sử dụng mã này:

SignatureWriter signature = new SignatureWriter(); 
signature.visitFormalTypeParameter("K"); 

// Ensure that <K> extends java.lang.Object 
{ 
    SignatureVisitor classBound = signature.visitClassBound(); 
    classBound.visitClassType(Type.getInternalName(Object.class)); 
    classBound.visitEnd(); 
} 

// The parameter uses the <K> type variable 
signature.visitParameterType().visitTypeVariable("K"); 

// The return type uses the void primitive ('V') 
signature.visitReturnType().visitBaseType('V'); 

signature.visitEnd(); 

String signatureString = signature.toString(); 

Đó là tương đương với:

String signatureString = "<K:Ljava/lang/Object;>(TK;)V;" 
+0

Điều này rất hữu ích, cảm ơn. Vấn đề cụ thể của tôi ngay bây giờ có vẻ là chữ ký kết quả bằng cách nào đó không được viết đúng trong tệp lớp, mặc dù tôi sử dụng định dạng đúng (theo như tôi biết). Nhưng có lẽ tôi nên kiểm tra lại với SignatureWriter để đảm bảo ... – StaxMan

+1

@StaxMan: Tôi cũng đã chia sẻ rắc rối với nó. Có lẽ bài viết này sẽ giúp: [Bộ công cụ phân loại: Generics with ASM] (http://www.ibm.com/developerworks/java/library/j-cwt02076.html) –

+0

Ah! Tôi cuối cùng đã tìm thấy vấn đề thực sự trong mã của tôi: Tôi đã có đối số V1_2 trong ClassVisitor.visit(); và điều này cần phải được V1_5 trở lên để được hỗ trợ (và chú thích). Cảm ơn bạn đã giúp đỡ! – StaxMan

-1

Trong kinh nghiệm của tôi hầu hết các thư viện thế hệ bytecode on-the-fly không có hỗ trợ tốt cho các loại generic, tuy nhiên các lớp bị xóa chỉ hoạt động tốt (trừ khi bạn muốn xem xét các lớp đó sau, tất nhiên)

+1

Đáng tiếc là tôi đặc biệt cần phải quan tâm - đó là cách sử dụng thư viện sẽ thực sự xây dựng serializers và deserializers. : -/ Có, việc xóa mã sẽ hoạt động ok ... và tôi có thể phải tìm một cách khác để làm cho mọi thứ hoạt động, có lẽ bằng cách thêm các loại chú thích mới để nhân rộng chữ ký hiệu quả. – StaxMan

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