AppletTalk.com Forum Index AppletTalk.com
Java discussions newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implementare serializzazione [lunghetto...]

 
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java (Italian)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Mon May 21, 2007 1:40 pm    Post subject: Implementare serializzazione [lunghetto...] Reply with quote



Salve a tutti.

Avrei un quesito da porre, penso sia una questione interessante.

Vorrei effettuare la serializzazione di oggetti senza però sfruttare i
meccanismi standard messi a disposizione dalla jvm, ma solo lato
software. E' tecnicamente possibile farlo per istanze di classi
qualsiasi?

Per classi qualsiasi intendo classi generiche senza "convenzioni"
speciali sul codice, quindi non dando per scontato che siano, ad
esempio, i vari metodi get per gli attributi oppure costruttori ad
hoc.

Mediante il medodo getDeclaredFields() della classe Class ho visto che
e' possibile scorrere tutti gli attributi, ma con le impostazioni
standard di sicurezza della jvm non e' possibile accedere al loro
contenuto (attributi private). Quindi l'unica soluzione che mi e'
venuta in mente e' presupporre la presenza dei metodi get per ogni
attributo (quindi classi ad hoc, non qualsiasi), oppure modificare la
politica di sicurezza della jvm per l'applicativo, anche se mi sembra
brutto.

E comunque c'è un altro problema. Ammettiamo di avere il permesso
dalla jvm di accedere ai membri private, tramite ricorsione posso
accedere a tutti gli attributi, ma come si fa per il processo inverso?

Supponiamo di avere una tabella che contiene i campi nome attributo -
valore, e di voler ricostruire l'oggetto. Se ho capito bene, guardando
le api, non so se mi sfugge qualcosa, l'unico modo per creare un
oggetto nuovo, anche con la riflessione, è invocare il corrispondente
costruttore.

La classe Class dispone del metodo newInstance(), che pero' utilizza
il costruttore vuoto per la creazione, dunque dovrei supporre la
presenza di un costruttore vuoto. Tramite il metodo
getDeclaredConstructors() posso accedere a tutti i costruttori, ma
come faccio a sapere quale è quello giusto, e chi mi dice che esista
un costruttore che inizializza tutti gli attributi? Ad esempio una
classe dato puo' avere un costruttore Dato(int id, int value), ma a
runtime come faccio a sapere che come primo parametro devo dargli l'id
e come secondo il valore, visto che l'unica informazione che posso
avere e' la presenza di un costruttore che accetta due int?

Per questo motivo, a meno che non mi smentiate, l'unica soluzione che
mi viene in mente e' porre delle convenzioni sul codice delle classi
che dovranno essere serializzate.

A tal fine, ho pensato che basterebbe disporre per ogni classe di un
array di stringhe che indica la lista degli attributi da serializzare,
per ogni attributo indicato deve esistere un corrispondente metodo
get, e deve esistere un costruttore che accetta in ingresso gli
attributi come indicati nell'array.

Ho pensato a due soluzioni: si potrebbe usare una annotation per la
classe del tipo @DataAttributes({"id","value"}), oppure implementare
una interfaccia che contiene un metodo dataAttributes() : String[] che
restituisce la lista degli attributi.

Secondo voi qual'è la soluzione migliore? La seconda consente di avere
un supertipo che identifica le classi serializzabili, comodo per un
uso coi generics, la prima mi sembra piu' "elegante".

Un altro tipo di soluzione potrebbe essere prevedere un metodo
serializeData() : byte[] che restituisce un array di byte con
l'oggetto serializzato, e relativo costruttore; oppure usare a tal
fine toString(), però non mi piace tanto perchè preferirei delegare le
operazioni di serializzazione al sistema e non all'applicazione.

Grazie dell'attenzione.

Marco
Back to top
Scorpio
Guest





PostPosted: Tue May 22, 2007 12:34 am    Post subject: Re: Implementare serializzazione [lunghetto...] Reply with quote



<marco (AT) fantaclub (DOT) it> ha scritto nel messaggio
news:1179736853.078622.75410 (AT) b40g2000prd (DOT) googlegroups.com...
Quote:
Salve a tutti.

Avrei un quesito da porre, penso sia una questione interessante.

Vorrei effettuare la serializzazione di oggetti senza però sfruttare i
meccanismi standard messi a disposizione dalla jvm, ma solo lato
software. E' tecnicamente possibile farlo per istanze di classi
qualsiasi?

Beh, qualche condizione al contorno devi pur mettercela, almeno
così di primo acchito... Una possibile idea sarebbe memorizzare
lo stato della tua classe in XML, scrivendoti a mano un serializzatore
ed un deserializzatore.

Quote:
Per classi qualsiasi intendo classi generiche senza "convenzioni"
speciali sul codice, quindi non dando per scontato che siano, ad
esempio, i vari metodi get per gli attributi oppure costruttori ad
hoc.

Mediante il medodo getDeclaredFields() della classe Class ho visto che
e' possibile scorrere tutti gli attributi, ma con le impostazioni
standard di sicurezza della jvm non e' possibile accedere al loro
contenuto (attributi private).

Però con la reflection si riesce a forzare la mano la JVM e a rendere
accessibili anche le variabili private, ad esempio così:

public class MyClass {
private int x;

public MyClass() {
}

public void print() {
System.out.println(x);
}

} // Classe stupida di esempio

MyClass prova = new MyClass();

Field f = prova.getClass().getDeclaredField("campoConVisibilitàPrivata");
f.setAccessible(true);
f.setInt(prova,12);
prova.print();



Quote:
Quindi l'unica soluzione che mi e'
venuta in mente e' presupporre la presenza dei metodi get per ogni
attributo (quindi classi ad hoc, non qualsiasi), oppure modificare la
politica di sicurezza della jvm per l'applicativo, anche se mi sembra
brutto.

Niente di tutto questo.

Quote:
E comunque c'è un altro problema. Ammettiamo di avere il permesso
dalla jvm di accedere ai membri private, tramite ricorsione posso
accedere a tutti gli attributi, ma come si fa per il processo inverso?

Il tuo deserializzatore deve essere in grado di rigenerare dal "dump" dello
stato della tua classe un'istanza i cui attributi siano valorizzati di
conseguenza.

Quote:
Supponiamo di avere una tabella che contiene i campi nome attributo -
valore, e di voler ricostruire l'oggetto. Se ho capito bene, guardando
le api, non so se mi sfugge qualcosa, l'unico modo per creare un
oggetto nuovo, anche con la riflessione, è invocare il corrispondente
costruttore.

Esatto.

Quote:
La classe Class dispone del metodo newInstance(), che pero' utilizza
il costruttore vuoto per la creazione, dunque dovrei supporre la
presenza di un costruttore vuoto. Tramite il metodo
getDeclaredConstructors() posso accedere a tutti i costruttori, ma
come faccio a sapere quale è quello giusto, e chi mi dice che esista
un costruttore che inizializza tutti gli attributi? Ad esempio una
classe dato puo' avere un costruttore Dato(int id, int value), ma a
runtime come faccio a sapere che come primo parametro devo dargli l'id
e come secondo il valore, visto che l'unica informazione che posso
avere e' la presenza di un costruttore che accetta due int?

Naturalmente la signature di un metodo, o di un costruttore, precisa
la sintassi del metodo ma non la sua semantica. Che diavolo significano
i due interi del costruttore è desumibile dalla documentazione e basta.

Quote:
Per questo motivo, a meno che non mi smentiate, l'unica soluzione che
mi viene in mente e' porre delle convenzioni sul codice delle classi
che dovranno essere serializzate.

[CUT]

L'avere un costruttore vuoto non mi sembra una condizione molto stringente,
no ?

Quote:
Ho pensato a due soluzioni: si potrebbe usare una annotation per la
classe del tipo @DataAttributes({"id","value"}), oppure implementare
una interfaccia che contiene un metodo dataAttributes() : String[] che
restituisce la lista degli attributi.

Secondo voi qual'è la soluzione migliore? La seconda consente di avere
un supertipo che identifica le classi serializzabili, comodo per un
uso coi generics, la prima mi sembra piu' "elegante".

Mah, dipende.. la soluzione di non prevedere nè setter nè getter ovviamente
è quella
più veloce ma anche la più "sporca". Non ho ben capito come vorresti usare
l'annotation @DataAttributes, occhio che value è read-only e a runtime non
puoi cambiarlo.

Quote:
Un altro tipo di soluzione potrebbe essere prevedere un metodo
serializeData() : byte[] che restituisce un array di byte con
l'oggetto serializzato, e relativo costruttore; oppure usare a tal
fine toString(), però non mi piace tanto perchè preferirei delegare le
operazioni di serializzazione al sistema e non all'applicazione.

Qui mi sorge un dubbio, però: la serializzazione standard di Java fa
*esattamente* un dump
a livello di byte, quindi perchè penare per ricostruire ciò che già c'è e
funziona ? Tieni
presente che anche la serializzazione XML esiste già e funziona. Mi sfugge
lo scopo che
sta dietro alle tue intenzioni.


Quote:
Grazie dell'attenzione.

Figurati, secondo me il tuo post la meritava.

Quote:
Marco

Scorpio.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java (Italian) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.