Perché Java ha bisogno dell’interfaccia serializzabile?

Lavoriamo pesantemente con la serializzazione e dover specificare tag Serializable su ogni object che usiamo è un po ‘oneroso. Soprattutto quando si tratta di una class di terze parti che non possiamo davvero cambiare.

La domanda è: dato che Serializable è un’interfaccia vuota e Java fornisce una seria serializzazione una volta aggiunte le implements Serializable – perché non hanno reso tutto serializzabile e basta?

Cosa mi manca?

La serializzazione è piena di insidie. Il supporto automatico per la serializzazione di questo modulo rende la parte interna della class dell’API pubblica (ecco perché javadoc fornisce le forms persistenti di classi ).

Per la persistenza a lungo termine, la class deve essere in grado di decodificare questo modulo, che limita le modifiche che è ansible apportare alla progettazione della class. Questo rompe l’incapsulamento.

La serializzazione può anche portare a problemi di sicurezza. Essendo in grado di serializzare qualsiasi object a cui fa riferimento, una class può accedere ai dati che normalmente non sarebbe in grado di (analizzando i dati byte risultanti).

Ci sono altri problemi, come la forma serializzata delle classi interne che non è ben definita.

Rendere serializzabili tutte le classi aggraverebbe questi problemi. Dai un’occhiata a Java Second Edition efficace , in particolare all’articolo 74: Implementare seriamente Serializable .

Penso che sia la gente di Java che quella di .Net abbiano sbagliato questa volta, sarebbe stato meglio rendere tutto serializzabile per impostazione predefinita e solo contrassegnare quelle classi che invece non possono essere serializzate in modo sicuro.

Ad esempio in Smalltalk (un linguaggio creato negli anni ’70) ogni object è serializzabile per impostazione predefinita. Non ho idea del perché questo non sia il caso in Java, considerando il fatto che la maggior parte degli oggetti è sicura da serializzare e solo alcuni di essi non lo sono.

Contrassegnare un object come serializzabile (con un’interfaccia) non rende magicamente serializzabile quell’object, è sempre stato serializzabile , è solo che ora hai express qualcosa che il sistema avrebbe potuto trovare da solo, quindi non vedo alcun vero motivo per la serializzazione è come è ora.

Penso che sia stata una scelta sbagliata dei progettisti o la serializzazione è stata un ripensamento, o la piattaforma non è mai stata pronta a fare la serializzazione di default su tutti gli oggetti in modo sicuro e coerente.

Non tutto è veramente serializzabile. Prendi una connessione socket di rete, per esempio. Potresti serializzare i dati / stato del tuo object socket, ma l’essenza di una connessione triggers andrebbe persa.

Il ruolo principale di Serializable in Java consiste nel rendere, per impostazione predefinita, tutti gli altri oggetti non serializzabili. La serializzazione è un meccanismo molto pericoloso, specialmente nella sua implementazione predefinita. Quindi, come l’amicizia in C ++, è distriggersto di default, anche se costa un po ‘di tempo per rendere le cose serializzabili.

La serializzazione aggiunge vincoli e potenziali problemi poiché la compatibilità della struttura non è assicurata. È bene che sia distriggersto per impostazione predefinita.

Devo ammettere che ho visto pochissime classi non banali in cui la serializzazione standard fa ciò che voglio. Soprattutto nel caso di strutture dati complesse. Quindi lo sforzo che si spenderebbe rendendo il serializble di class nani equivale al costo di aggiungere l’interfaccia.

Per alcune classi, specialmente quelle che rappresentano qualcosa di più fisico come un file, un socket, un thread o una connessione DB, non ha assolutamente senso serializzare le istanze. Per molti altri, la serializzazione può essere problematica perché distrugge i vincoli di unicità o semplicemente ti costringe a gestire istanze di diverse versioni di una class, cosa che potresti non volere.

Probabilmente, sarebbe stato meglio rendere tutto serializzabile di default e rendere le classi non serializzabili attraverso una parola chiave o un’interfaccia marcatore – ma poi, chi dovrebbe usare quell’opzione probabilmente non ci penserebbe. In questo modo, se hai bisogno di implementare Serializable, ti verrà detto da un’eccezione.

Penso che il pensiero fosse quello di assicurarti che, come programmatore, sappia che il tuo object può essere serializzato.

Apparentemente tutto era serializzabile in alcuni progetti preliminari, ma a causa della sicurezza e della correttezza il design finale è finito come tutti sappiamo.

Fonte: perché le classi devono implementare Serializable per poter essere scritte su ObjectOutputStream? .

Dovendo dichiarare esplicitamente che le istanze di una certa class sono serializzabili, il linguaggio ti costringe a pensare se dovresti permetterlo. Per la serializzazione di oggetti di valore semplice è banale, ma nei casi più complessi è necessario pensare veramente alle cose.

Facendo semplicemente affidamento sul supporto di serializzazione standard della JVM ti esponi a tutti i tipi di problemi di versioning.

Unicità, riferimenti a risorse “reali”, timer e molti altri tipi di artefatti NON sono candidati per la serializzazione.

Leggi questo per capire l’interfaccia serializzabile e perché dovremmo rendere solo poche classi serializzabili e inoltre dovremmo occuparci di dove usare la parola chiave transitoria nel caso in cui vogliamo rimuovere alcuni campi dalla procedura di memorizzazione.

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/

Bene, la mia risposta è che questo è senza una buona ragione. E dai tuoi commenti posso vedere che lo hai già imparato. Altre lingue tentano con piacere di serializzare tutto ciò che non salta su un albero dopo aver contato fino a 10. Un object dovrebbe essere serializzato come predefinito.

Quindi, quello che devi fare è leggere tutte le proprietà della tua class di terze parti. Oppure, se questa è un’opzione per te: decompila, inserisci la dannata parola chiave lì e ricompila.

Ci sono alcune cose in Java che semplicemente non possono essere serializzate perché sono specifiche del runtime. Cose come stream, thread, runtime, ecc. E persino alcune classi della GUI (che sono collegate al sistema operativo sottostante) non possono essere serializzate.

Mentre sono d’accordo con i punti formulati in altre risposte qui, il vero problema è con la deserializzazione: se la definizione della class cambia, c’è un rischio reale che la deserializzazione non funzioni. Non modificare mai i campi esistenti è un impegno piuttosto importante per l’autore di una libreria! Mantenere la compatibilità con le API è già abbastanza complicato.

Una class che deve essere mantenuta su un file o su un altro supporto deve implementare un’interfaccia Serializable, in modo che JVM possa consentire la serializzazione dell’object di class. Perché la class Object non è serializzata, quindi nessuna delle classi deve implementare l’interfaccia, dopotutto la JVM serializza la class solo quando utilizzo ObjectOutputStream, il che significa che il controllo è ancora nelle mie mani per consentire alla JVM di serializzare.

Il motivo per cui la class Object non è serializzabile per impostazione predefinita nel fatto che la versione della class è il problema principale. Pertanto, ogni class interessata alla serializzazione deve essere contrassegnata come Serializable esplicitamente e fornire un numero di versione serialVersionUID.

Se serialVersionUID non viene fornito, otteniamo risultati imprevisti durante la deserializzazione dell’object, ecco perché JVM lancia InvalidClassException se serialVersionUID non corrisponde. Pertanto, ogni class deve implementare un’interfaccia serializzabile e fornire serialVersionUID per assicurarsi che la class presentata alle due estremità sia identica.