2012-05-29 27 views
9

Tôi muốn tạo hàm tổng quát trả về biểu diễn đối tượng của tài liệu XML (sử dụng JAXB). Tôi cần phải vượt qua "class" đối tượng để JAXBContext constructor, nhưng làm thế nào tôi có thể nhận được nó từ T?Nhận đối tượng "Lớp" từ kiểu chung T

public <T> readXmlToObject(String xmlFileName, T jaxbClass) { 
    JAXBContext context = JAXBContext.newInstance(T.class); // T.class - here error, how to get it? 
    ....... 
} 
+1

tìm kiếm cho 'loại chô bôi' :-) –

Trả lời

13

Vượt qua đối tượng lớp học thay thế và thật dễ dàng.

public <T> T readXmlToObject(String xmlFileName, Class<T> jaxbClass) { 
     JAXBContext context = JAXBContext.newInstance(jaxbClass); // T.class - here error, how to get it? 
     Object o = context.createUnmarshaller().unmarshal(new File(xmlFileName)); 
     return jaxbClass.cast(o); 
} 

Ý tưởng ở đây là vì bạn không thể trích xuất các tham số kiểu từ đối tượng, bạn phải làm điều đó theo cách khác xung quanh: bắt đầu với lớp và sau đó thao tác các đối tượng để phù hợp với tham số kiểu.

+0

(Tôi không nghĩ rằng '? Extends' mua cho bạn bất cứ điều gì ở đây.) –

+0

@ TomHawtin-tackline Bạn nói đúng. – biziclop

3

Bạn không thể truy cập lớp học vào thời gian chạy. Java thực hiện Generics bằng cách sử dụng loại Erasure an toàn có nghĩa là sự hiểu biết về loại Generic chỉ được áp dụng tại thông qua biên dịch. Bạn phải interogate đối tượng thực tế tại thời gian chạy nếu bạn muốn để có được lớp của nó.

+2

-1 sai! Lớp học đang được thông qua. Vấn đề là với chữ ký phương thức – Bohemian

+1

Cảm ơn bạn đã nhập. Theo văn bản nó sẽ không hoạt động, nhưng tôi thấy quan điểm của bạn với việc thay đổi đầu vào thành Class thay vì T. Điều đó sẽ ổn thôi. Nó sẽ là tốt đẹp mặc dù, nếu nó thậm chí không phải là một mối quan tâm vì Java Generics xấu impl. –

+0

Tôi đã xóa bỏ phiếu giảm giá của tôi - câu trả lời của bạn không phải * rằng * sai :) – Bohemian

1

Hãy xem this SO answer.

Về cơ bản, loại T không khả dụng khi chạy - các Generics Java phải tuân thủ erasure by the compiler.

May mắn thay bạn đã có một thể hiện của lớp học của bạn, vì vậy bạn có thể nhận được thông tin loại từ đó:

public <T> readXmlToObject(String xmlFileName, T jaxbClass) { 

    // if jaxbClass is an instance of the data object, you can do this: 
    JAXBContext context = JAXBContext.newInstance(jaxbClass.getClass()); 

    // alternatively if jaxbClass is an instance of the Class object: 
    JAXBContext context = JAXBContext.newInstance(jaxbClass); 
    // ...... 
} 
+0

-1 Hoàn toàn không hoạt động. 'jaxbClass.getClass()' sẽ trả về 'Class.class'. Và bạn cũng sai - tẩy xoá không phải là một vấn đề ở đây vì lớp học đang được chuyển vào. – Bohemian

+0

ah - Tôi giả định rằng bởi vì nó bị ràng buộc với T thay vì lớp rằng nó là một thể hiện của lớp (nếu bạn nhận được trôi dạt của tôi ...) –

+0

Tôi nhận được bạn, nhưng nghĩ rằng đó là vấn đề của mình - anh ta đã mã hóa loại sai cho tham số. Anh ta * không phải là * đi qua một 'T', bởi vì anh ta sẽ không có một ví dụ' T' cho đến sau cuộc gọi, nhưng anh ta có thể vượt qua trong một thể hiện của 'Class '. Tôi thừa nhận rằng tôi sẽ theo tên tham số 'jaxbClass', điều này khá mạnh mẽ cho thấy đó là một' lớp'. – Bohemian

1

cố gắng để vượt qua các lớp chính nó, một cái gì đó như thế này

public <T> readXmlToObject(String xmlFileName, Class<T> class) { 
6

Don' Hãy lắng nghe những người khác ... bạn CÓ THỂ lấy nó.

Đơn giản chỉ cần thay đổi kiểu của tham số jaxbClass để Class<T>:

public <T> T readXmlToObject(String xmlFileName, Class<T> jaxbClass) { 
    JAXBContext context = JAXBContext.newInstance(jaxbClass); 
    ....... 
} 
0
public class XYZ<T> { 
    ... 
    private Class<T> tClass;  
    ... 
    public <T> readXmlToObject(String xmlFileName) { 
     JAXBContext context = JAXBContext.newInstance(tClass); 
     ... 
    } 
    ... 
} 
+0

Tôi không nghĩ rằng điều này sẽ làm việc vì tClass không được khởi tạo và bạn kết thúc bằng một giá trị rỗng cho cuộc gọi "JAXBContext.newInstance (..)". –

+0

Bạn nói đúng, @ go-rose-hulman. –

+1

Trong mã của tôi, tôi đã làm như thế này: private Class entityClass; cuối cùng ParameterizedType type = (ParameterizedType) getClass(). getGenericSuperclass(); entityClass = (Loại ) type.getActualTypeArguments() [0]; –

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