2011-09-12 5 views
6

Trong chương trình của tôi, tôi xử lý các lớp và các kiểu nguyên thủy. Nếu chương trình tìm thấy một lớp, nó chỉ đơn giản thực hiện một trong những cuộc gọi sau đây:Làm thế nào để có được loại lớp nguyên thủy với Javassist?

  • Class.forName(classname)
  • cc.toClass() nơi cc là một thể hiện của CtClass

Tuy nhiên, nếu nó tìm thấy một loại nguyên thủy, mọi thứ trở nên tồi tệ hơn:

  • Class.forName không sử dụng được, không thể sử dụng với các kiểu nguyên thủy.
  • cc.toClass() lợi nhuận null

Có thể gọi lĩnh vực TYPE từ các loại nguyên thủy bao bọc lớp nhưng làm thế nào tôi có thể làm điều đó với sự phản ánh?

Đây là mã của tôi:

CtClass cc;//Obtained from caller code 
Class<?> classParam; 
if (cc.isprimitive()) { 
    classParam= ?? // How can I get TYPE field value with reflection ? 
} else { 
    String nomClasseParam = cc.getName(); 

    if (nomClasseParam.startsWith("java")) { 
     classeParam = Class.forName(nomClasseParam); 
    } else { 
     classeParam = cc.toClass(); 
    } 
} 

Javassist 3.12.0.GA

EDIT: Tôi đã đăng the solution I chose trong anwsers dưới đây. Dù sao, tôi đã đánh dấu Tom's answer.

+2

Câu hỏi khác này chắc chắn sẽ giúp: [boolean.class?] (Http://stackoverflow.com/questions/1019208/boolean-class) –

+0

@Andreas_D Không nhiều kể từ khi tôi muốn thực hiện cuộc gọi với sự phản chiếu java. – Stephan

+0

nhưng chúng tôi * có thể * sử dụng 'boolean.class',' int.class' và các đối tượng 'Lớp' khi chúng ta phản ánh các phương thức và hàm dựng –

Trả lời

5

Dường như với tôi như bạn có thể truyền cc đến phân lớp của nó CtPrimitiveType.

Nếu bạn muốn có trình bao bọc, bạn có thể sử dụng phương pháp getWrapperName để lấy tên lớp của trình bao bọc phù hợp. Bạn có thể sử dụng Class.forName như thường lệ để biến tên đó thành đối tượng Class. Tuy nhiên, tôi không nghĩ rằng bạn muốn có một wrapper, vì vậy điều này không giúp đỡ.

Thay vào đó, tôi nghĩ rằng bạn muốn getDescriptor, tiếp theo là một câu lệnh switch chăm handcoded:

switch(descriptor) { 
    case 'I': classParam = int.class; break; 
    // etc 
} 

Something như vậy thực sự phải ở trong Javassist. Nhưng theo như tôi có thể thấy, nó không phải là.

+0

' getDescriptor' tại sao không, báo cáo chuyển đổi mất thời gian để viết mặc dù ... – Stephan

+0

Cuối cùng, tôi sử dụng 'getWrapperName' và tôi tránh phải viết mã lệnh chuyển đổi. – Stephan

+0

Cho rằng chỉ có tám kiểu nguyên thủy , nó sẽ không * mà * mất thời gian để viết. –

1

Bạn có thể làm Class.forName cho trình bao bọc đối tượng nguyên thủy (ví dụ: Số nguyên cho int nguyên thủy). Java hỗ trợ autoboxing, vì vậy bạn có thể trao đổi giữa wrapper Object và đối tác nguyên thủy.

Tôi giả định rằng bạn đang sử dụng CtClass từ JavaAssist. Nếu cc là nguyên thủy, tôi nghĩ rằng nó sẽ là một loại CtPrimitiveType (cần xác nhận) trong trường hợp này bạn có thể truyền và gọi getWrapperName() để nhận lớp trình bao bọc.

+1

Không đúng trong thế giới phản chiếu. :( – dacwe

+0

Bạn nói đúng, Java hỗ trợ autoboxing nhưng lớp tôi thao tác được tạo bởi Javassist, lớp được tạo ra có một phương thức với tham số 'int'. Trình nạp lớp không thể tìm thấy phương thức này nếu tôi đưa cho anh ta' java. tham số lang.Integer' trong 'Class.forName'. – Stephan

+0

@dawce Argh, tôi không biết rằng: (Nên chơi với sự phản ánh nhiều hơn Stephan trông giống như câu trả lời của Tom sẽ hoạt động. – momo

3

Dựa trên phản hồi của Tom và momo, đây là giải pháp tôi đến với:

CtClass cc; //Obtained from caller code 
Class<?> classParam; 

if (cc.isprimitive()) { 
    classParam = Class.forName(((CtPrimitiveType)cc).getWrapperName()); 
    classParam = (Class<?>)classParam.getDeclaredField("TYPE").get(classParam); 
} else { 
    String nomClasseParam = cc.getName(); 

    if (nomClasseParam.startsWith("java")) { 
     classeParam = Class.forName(nomClasseParam); 
    } else { 
     classeParam = cc.toClass(); 
    } 
} 

tôi gọi CtPrimitiveType#getWrapperName phương pháp và sau đó tôi sử dụng trường TYPE để có được những lớp học kiểu nguyên thủy.Tôi cũng tránh viết một tuyên bố chuyển đổi.

Cảm ơn các bạn đã giúp đỡ.