2010-11-11 14 views
15

Che cosa deve fare JAXB per un costruttore no-arg pubblico durante il marshalling?Per che JAXB ha bisogno di un costruttore no-arg pubblico?

Marshaller msh = ctx.createMarshaller(); 
msh.marshal(object, System.out); 

Sto passando un oggetto, non una classe. Perché JAXB ha bisogno di un costruttore? Per costruire cosa?

+0

Nitpick: Sono abbastanza sicuro che non sia necessario un costruttore * public * no-arg. Ha solo bisogno di * qualsiasi * costruttore no-arg. Può essere protetto/privato/pacchetto-privato, se lo desideri. – MatrixFrog

risposta

6

Un'implementazione JAXB non dovrebbe richiedere un costruttore no-arg durante un'operazione di marshalling. JAXB ne richiede uno per unmarshalling. Normalmente l'assenza di un costruttore no-arg causa un errore quando viene creato il JAXBContext. L'implementazione JAXB in uso potrebbe ritardare l'inizializzazione finché non viene eseguita un'operazione effettiva.

In generale il supporto per i costruttori multi-arg è qualcosa che dovremmo considerare in una versione futura di JAXB. Nel EclipseLink implementation of JAXB (MOXy) abbiamo una richiesta di miglioramento aperta per questa funzionalità (sentitevi liberi di aggiungere dettagli pertinenti):

Nella versione attuale di JAXB si potrebbe usare un XMLAdapter per sostenere questo caso d'uso:

+0

Con 'XmlAdapter' Devo conoscere la struttura interna della classe in fase di marshalling. In questo caso, perché non posso semplicemente aggiungere un costruttore no-arg? – yegor256

+2

@Vincenzo potresti semplicemente aggiungere un costruttore no-arg. Se per qualche motivo non è possibile modificare le classi del modello, è possibile utilizzare un XmlAdapter. –

4

Lo stesso di molti framework: semplicità e coerenza. Permette alla libreria di chiamare semplicemente Class.newInstance() senza doversi preoccupare di come specificare certe dipendenze per un costruttore che le prende. JAXB non vuole occuparsi di Full-on Injection di dipendenza al di sopra e al di là dell'impostazione basata sugli attributi che già fa.

È un peccato in qualche modo perché significa che queste classi non possono essere immutabili, ma questo è il compromesso da fare.

+0

Finché non si specifica quale parametro è il punto nel costruttore, non vedo alcun modo per JAXB per scoprirlo. La reflection api fornisce solo i tipi, nessun nome per gli argomenti al costruttore. Come dovrebbe sapere che il primo parametro (String) è il nome e non un ID o sthg del genere? – ZeissS

+1

Correzione a me stesso: l'annotazione potrebbe risolvere questo ... – ZeissS

+3

So cosa è un costruttore no-arg pubblico, ma perché JAXB ne ha bisogno durante il marshalling? Sto passando un'istanza a 'marshal()', non a una classe. – yegor256

5

Come altri hanno notato, non dovrebbe davvero bisogno di uno, ma (almeno nell'implementazione di Sun) lo fa. È possibile aggirare questo con un fittizio costruttore:

private MyObject() { 
    throw new UnsupportedOperationException("No-arg constructor is just to keep JAXB from complaining"); 
} 
+0

Qui non puoi lanciare un'eccezione, JAXB usa effettivamente questo c-tor – Derp

+0

Dipende se JAXB sta costruendo l'oggetto o se ([come i commenti OP] (http://stackoverflow.com/questions/4155361/what- jaxb-needs-a-public-no-arg-constructor-per/12921496? noredirect = 1 # comment4484733_4155388)) lo stai costruendo da solo e passando un'istanza a 'marshal()'. –

Problemi correlati