2012-05-29 18 views
9

Quiero hacer una función genérica que devuelva la representación del Objeto del documento XML (usando JAXB). Necesito pasar el objeto "clase" al constructor JAXBContext, pero ¿cómo puedo obtenerlo desde T?Obtiene el objeto "Clase" del tipo genérico T

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

búsqueda de 'tipo borrado' :-) –

Respuesta

13

Pase el objeto clase en su lugar y es fácil.

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); 
} 

La idea aquí es que, dado que no se puede extraer el parámetro de tipo de objeto, hay que hacerlo al revés: se inicia con la clase y luego manipular el objeto para que coincida con el parámetro de tipo.

+0

(No creo que el '? Extends' te compre nada aquí) –

+0

@ TomHawtin-tackline Tienes razón. – biziclop

3

No se puede obtener la clase en tiempo de ejecución. Java implementa Generics utilizando Type Safe Erasure, lo que significa que la comprensión del tipo genérico solo se aplica a través de la compilación. Debe interpolar el objeto real en tiempo de ejecución si desea obtener su clase.

+2

-1 incorrecto! La clase se está transfiriendo. El problema es con el método signature – Bohemian

+1

Gracias por la entrada. Tal como está escrito, no funcionaría, pero veo tu punto al cambiar la entrada a la clase en lugar de a T. Eso estaría bien. Sin embargo, sería bueno si no fuera una preocupación debido a la mala implementación de genéricos de Java. –

+0

Quité mi voto negativo - tu respuesta no es * que * está equivocada :) – Bohemian

1

Eche un vistazo a this SO answer.

Básicamente, el tipo T no está disponible en tiempo de ejecución: los genéricos de Java están sujetos a erasure by the compiler.

Afortunadamente ya tiene una instancia de la clase, para que pueda obtener la información de tipo de allí:

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 Totalmente no funcionará. 'jaxbClass.getClass()' devolverá 'Class.class'. Y también estás equivocado, el borrado no es un problema aquí porque la clase se está transfiriendo. – Bohemian

+0

ah - Supuse que porque estaba limitado a T en lugar de a la clase que era una instancia de la clase (si obtienes mi deriva ...) –

+0

Te entiendo, pero creo que ese es su problema, ha codificado el tipo incorrecto para el parámetro. He * no está * pasando una 'T', porque no tendrá una instancia de' T' hasta después de la llamada, pero puede pasar una instancia de 'Clase '. Admito que voy por el nombre del parámetro 'jaxbClass', que bastante fuertemente sugiere que es una' clase'. – Bohemian

1

tratar de pasar a la clase en sí, algo así

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

Don' Escucha a los demás ... PUEDES obtenerlo.

basta con cambiar el tipo del parámetro jaxbClass a 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

No creo que esto funcione porque tClass no se inicializa y termina pasando un nulo a la llamada "JAXBContext.newInstance (..)". –

+0

Tienes razón, @ go-rose-hulman. –

+1

En mi código lo hice así: private Class entityClass; final ParameterizedType type = (ParameterizedType) getClass(). getGenericSuperclass(); entityClass = (Clase ) type.getActualTypeArguments() [0]; –

Cuestiones relacionadas