Cosa si intende per "serializzazione degli oggetti"? Puoi per favore spiegarlo con alcuni esempi?
Cosa si intende per "serializzazione degli oggetti"? Puoi per favore spiegarlo con alcuni esempi?
Risposte:
La serializzazione è la conversione di un oggetto in una serie di byte, in modo che l'oggetto possa essere facilmente salvato nella memoria permanente o trasmesso in streaming attraverso un collegamento di comunicazione. Il flusso di byte può quindi essere deserializzato, convertito in una replica dell'oggetto originale.
Puoi pensare alla serializzazione come al processo di conversione di un'istanza di oggetto in una sequenza di byte (che può essere binaria o non dipendente dall'implementazione).
È molto utile quando si desidera trasmettere i dati di un oggetto attraverso la rete, ad esempio da una JVM a un'altra.
In Java, il meccanismo di serializzazione è integrato nella piattaforma, ma è necessario implementare l' interfaccia Serializable per rendere serializzabile un oggetto.
È inoltre possibile impedire la serializzazione di alcuni dati nell'oggetto contrassegnando l'attributo come transitorio .
Finalmente puoi sovrascrivere il meccanismo predefinito e fornire il tuo; questo può essere adatto in alcuni casi speciali. Per fare questo, usi uno dei funzioni nascoste in Java .
È importante notare che ciò che viene serializzato è il "valore" dell'oggetto o dei contenuti e non la definizione della classe. Pertanto i metodi non sono serializzati.
Ecco un esempio molto semplice con commenti per facilitare la sua lettura:
import java.io.*;
import java.util.*;
// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {
// These attributes conform the "value" of the object.
// These two will be serialized;
private String aString = "The value of that string";
private int someInteger = 0;
// But this won't since it is marked as transient.
private transient List<File> unInterestingLongLongList;
// Main method to test.
public static void main( String [] args ) throws IOException {
// Create a sample object, that contains the default values.
SerializationSample instance = new SerializationSample();
// The "ObjectOutputStream" class has the default
// definition to serialize an object.
ObjectOutputStream oos = new ObjectOutputStream(
// By using "FileOutputStream" we will
// Write it to a File in the file system
// It could have been a Socket to another
// machine, a database, an in memory array, etc.
new FileOutputStream(new File("o.ser")));
// do the magic
oos.writeObject( instance );
// close the writing.
oos.close();
}
}
Quando eseguiamo questo programma, viene creato il file "o.ser" e possiamo vedere cosa è successo dietro.
Se cambiamo il valore di: someInteger in, ad esempio Integer.MAX_VALUE , potremmo confrontare l'output per vedere qual è la differenza.
Ecco uno screenshot che mostra esattamente quella differenza:
Riesci a individuare le differenze? ;)
C'è un ulteriore campo rilevante nella serializzazione Java: il serialversionUID ma immagino che questo sia già troppo lungo per coprirlo.
SerializationSample
SerializationSample instance = new SerializationSample();
quindi l'output viene creato e l'oggetto scritto su quell'output.
Osare rispondere alla domanda di 6 anni, aggiungendo una comprensione di altissimo livello per le persone che non conoscono Java
Che cos'è la serializzazione?
Conversione di un oggetto in byte
Che cos'è la deserializzazione?
Conversione di byte in un oggetto (deserializzazione).
Quando viene utilizzata la serializzazione?
Quando vogliamo persistere nell'oggetto. Quando vogliamo che l'oggetto esista oltre la durata della JVM.
Esempio del mondo reale:
Bancomat: quando il titolare del conto tenta di prelevare denaro dal server tramite bancomat, le informazioni sul titolare del conto, come i dettagli di prelievo, vengono serializzate e inviate al server in cui i dettagli vengono deserializzati e utilizzati per eseguire le operazioni.
Come viene eseguita la serializzazione in Java.
Implementare l' java.io.Serializable
interfaccia (interfaccia marker quindi nessun metodo da implementare).
Persistere l'oggetto: Usa java.io.ObjectOutputStream
classe, un flusso di filtro che è un wrapper attorno a un flusso di byte di livello inferiore (per scrivere l'oggetto su file system o trasferire un oggetto appiattito attraverso un filo di rete e ricostruito sull'altro lato).
writeObject(<<instance>>)
- per scrivere un oggetto readObject()
- leggere un oggetto serializzatoRicorda:
Quando si serializza un oggetto, verrà salvato solo lo stato dell'oggetto, non il file o i metodi della classe dell'oggetto.
Quando si serializza un oggetto a 2 byte, viene visualizzato un file serializzato di 51 byte.
Passa come l'oggetto viene serializzato e deserializzato.
Risposta per: Come è stato convertito in un file di 51 byte?
java.lang.Object
.Se sei interessato a informazioni più approfondite sulla serializzazione Java, controlla questo link .
Modifica : un altro link valido da leggere.
Questo risponderà ad alcune domande frequenti:
Come non serializzare alcun campo in classe.
Risposta: usa una parola chiave temporanea
Quando la classe figlio viene serializzata, la classe genitore viene serializzata?
Risp: No, se un genitore non estende il campo Genitori dell'interfaccia serializzabile non viene serializzato.
Quando un genitore è serializzato, la classe figlio viene serializzata?
Risp: Sì, per impostazione predefinita anche la classe figlio viene serializzata.
Come evitare che le classi secondarie vengano serializzate?
Ans: a. Sostituisci il metodo writeObject e readObject e lancia NotSerializableException
.
b. inoltre puoi contrassegnare tutti i campi transitori nella classe figlio.
La serializzazione sta prendendo in memoria un oggetto "live" e lo sta convertendo in un formato che può essere archiviato da qualche parte (ad es. In memoria, su disco) e successivamente "deserializzato" in un oggetto live.
Mi è piaciuto il modo in cui @OscarRyz si presenta. Anche se qui sto continuando la storia della serializzazione che è stata originariamente scritta da @amitgupta.
Sebbene conoscendo la struttura della classe dei robot e avendo dati serializzati, lo scienziato della Terra non è stato in grado di deserializzare i dati che possono far funzionare i robot.
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:
Gli scienziati di Mars stavano aspettando il pagamento completo. Una volta effettuato il pagamento, gli scienziati di Mars hanno condiviso il serialversionUID con gli scienziati della Terra. Lo scienziato della Terra lo ha impostato sulla classe dei robot e tutto è andato bene.
La serializzazione significa oggetti persistenti in Java. Se si desidera salvare lo stato dell'oggetto e ricostruire lo stato in un secondo momento (potrebbe essere in un'altra JVM), è possibile utilizzare la serializzazione.
Si noti che le proprietà di un oggetto verranno salvate. Se si desidera resuscitare nuovamente l'oggetto, è necessario disporre del file di classe, poiché verranno memorizzate solo le variabili membro e non le funzioni membro.
per esempio:
ObjectInputStream oos = new ObjectInputStream(
new FileInputStream( new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();
Searializable è un'interfaccia marker che indica che la tua classe è serializzabile. L'interfaccia Marker significa che è solo un'interfaccia vuota e l'utilizzo di tale interfaccia avviserà la JVM che questa classe può essere resa serializzabile.
I miei due centesimi dal mio blog:
Ecco una spiegazione dettagliata della serializzazione : (il mio blog)
serializzazione:
La serializzazione è il processo di persistenza dello stato di un oggetto. È rappresentato e memorizzato sotto forma di una sequenza di byte. Questo può essere memorizzato in un file. Il processo per leggere lo stato dell'oggetto dal file e ripristinarlo si chiama deserializzazione.
Qual è la necessità della serializzazione?
Nell'architettura moderna, è sempre necessario memorizzare lo stato dell'oggetto e quindi recuperarlo. Ad esempio in Hibernate, per memorizzare un oggetto dovremmo rendere la classe serializzabile. Ciò che fa è che una volta salvato lo stato dell'oggetto sotto forma di byte, può essere trasferito su un altro sistema che può quindi leggere dallo stato e recuperare la classe. Lo stato dell'oggetto può provenire da un database o da un jvm diverso o da un componente separato. Con l'aiuto della serializzazione possiamo recuperare lo stato dell'Oggetto.
Esempio di codice e spiegazione:
Per prima cosa diamo un'occhiata alla classe di oggetti:
public class Item implements Serializable{
/**
* This is the Serializable class
*/
private static final long serialVersionUID = 475918891428093041L;
private Long itemId;
private String itemName;
private transient Double itemCostPrice;
public Item(Long itemId, String itemName, Double itemCostPrice) {
super();
this.itemId = itemId;
this.itemName = itemName;
this.itemCostPrice = itemCostPrice;
}
public Long getItemId() {
return itemId;
}
@Override
public String toString() {
return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Double getItemCostPrice() {
return itemCostPrice;
}
public void setItemCostPrice(Double itemCostPrice) {
this.itemCostPrice = itemCostPrice;
}
}
Nel codice sopra si può vedere che la classe Item implementa Serializable .
Questa è l'interfaccia che consente a una classe di essere serializzabile.
Ora possiamo vedere una variabile chiamata serialVersionUID inizializzata su Variabile lunga. Questo numero viene calcolato dal compilatore in base allo stato della classe e agli attributi della classe. Questo è il numero che aiuterà jvm a identificare lo stato di un oggetto quando legge lo stato dell'oggetto dal file.
Per questo possiamo dare un'occhiata alla documentazione Oracle ufficiale:
Il runtime di serializzazione associa a ciascuna classe serializzabile un numero di versione, chiamato serialVersionUID, che viene utilizzato durante la deserializzazione per verificare che il mittente e il destinatario di un oggetto serializzato abbiano caricato classi per quell'oggetto compatibili rispetto alla serializzazione. Se il destinatario ha caricato una classe per l'oggetto che ha un serialVersionUID diverso da quello della classe del mittente corrispondente, la deserializzazione si tradurrà in InvalidClassException. Una classe serializzabile può dichiarare esplicitamente la propria serialVersionUID dichiarando esplicitamente un campo denominato "serialVersionUID" che deve essere statico, finale e di tipo lungo: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; Se una classe serializzabile non dichiara esplicitamente un serialVersionUID, quindi il runtime di serializzazione calcolerà un valore serialVersionUID predefinito per quella classe in base a vari aspetti della classe, come descritto nelle Specifiche di serializzazione degli oggetti Java (TM). Tuttavia, si raccomanda vivamente che tutte le classi serializzabili dichiarino esplicitamente i valori serialVersionUID, poiché il calcolo serialVersionUID predefinito è altamente sensibile ai dettagli della classe che possono variare a seconda delle implementazioni del compilatore e può quindi provocare eccezioni InvalidClassException impreviste durante la deserializzazione. Pertanto, per garantire un valore serialVersionUID coerente tra le diverse implementazioni del compilatore java, una classe serializzabile deve dichiarare un valore serialVersionUID esplicito. Si consiglia inoltre vivamente che dichiarazioni esplicite serialVersionUID utilizzino il modificatore privato ove possibile,
Se hai notato che abbiamo usato un'altra parola chiave che è temporanea .
Se un campo non è serializzabile, deve essere contrassegnato come transitorio. Qui abbiamo contrassegnato l' articoloCostPrice come transitorio e non vogliamo che sia scritto in un file
Ora diamo un'occhiata a come scrivere lo stato di un oggetto nel file e quindi leggerlo da lì.
public class SerializationExample {
public static void main(String[] args){
serialize();
deserialize();
}
public static void serialize(){
Item item = new Item(1L,"Pen", 12.55);
System.out.println("Before Serialization" + item);
FileOutputStream fileOut;
try {
fileOut = new FileOutputStream("/tmp/item.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(item);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in /tmp/item.ser");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void deserialize(){
Item item;
try {
FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
item = (Item) in.readObject();
System.out.println("Serialized data is read from /tmp/item.ser");
System.out.println("After Deserialization" + item);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In quanto sopra possiamo vedere un esempio di serializzazione e deserializzazione di un oggetto.
Per questo abbiamo usato due classi. Per serializzare l'oggetto abbiamo usato ObjectOutputStream. Abbiamo usato il metodo writeObject per scrivere l'oggetto nel file.
Per la deserializzazione abbiamo usato ObjectInputStream che legge dall'oggetto dal file. Utilizza readObject per leggere i dati dell'oggetto dal file.
L'output del codice sopra sarebbe simile a:
Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]
Si noti che itemCostPrice dall'oggetto deserializzato è null quanto non è stato scritto.
Abbiamo già discusso le basi della serializzazione Java nella parte I di questo articolo.
Ora discutiamolo a fondo e come funziona.
Per prima cosa iniziamo con il serialversionuid.
il serialVersionUID viene utilizzato come controllo di versione in una classe Serializable.
Se non dichiari esplicitamente un serialVersionUID, JVM lo farà automaticamente per te, in base a varie proprietà della classe Serializable.
Algorithm of Calculating serialversionuid di Java (Leggi maggiori dettagli qui)
- Il nome della classe
- I modificatori di classe scritti come un intero a 32 bit.
- Il nome di ciascuna interfaccia ordinata per nome.
- Per ogni campo della classe ordinato per nome campo (eccetto i campi transitori privati statici e privati: il nome del campo. I modificatori del campo scritti come un numero intero a 32 bit. Il descrittore del campo.
- Se esiste un inizializzatore di classe, scrivere quanto segue: Il nome del metodo,.
- Il modificatore del metodo, java.lang.reflect.Modifier.STATIC, scritto come un numero intero a 32 bit.
- Il descrittore del metodo, () V.
- Per ogni costruttore non privato ordinato per nome e firma del metodo: Il nome del metodo,. I modificatori del metodo scritti come un numero intero a 32 bit. Il descrittore del metodo.
- Per ogni metodo non privato ordinato per nome e firma del metodo: il nome del metodo. I modificatori del metodo scritti come un numero intero a 32 bit. Il descrittore del metodo.
- L'algoritmo SHA-1 viene eseguito sul flusso di byte prodotto da DataOutputStream e produce cinque valori a 32 bit sha [0..4]. Il valore hash viene assemblato dal primo e dal secondo valore a 32 bit del digest del messaggio SHA-1. Se il risultato del digest del messaggio, le cinque parole a 32 bit H0 H1 H2 H3 H4, si trova in una matrice di cinque valori int chiamati sha, il valore di hash verrebbe calcolato come segue:
long hash = ((sha[0] >>> 24) & 0xFF) |
> ((sha[0] >>> 16) & 0xFF) << 8 |
> ((sha[0] >>> 8) & 0xFF) << 16 |
> ((sha[0] >>> 0) & 0xFF) << 24 |
> ((sha[1] >>> 24) & 0xFF) << 32 |
> ((sha[1] >>> 16) & 0xFF) << 40 |
> ((sha[1] >>> 8) & 0xFF) << 48 |
> ((sha[1] >>> 0) & 0xFF) << 56;
Algoritmo di serializzazione di Java
L'algoritmo per serializzare un oggetto è descritto di seguito:
1. Scrive i metadati della classe associata a un'istanza.
2. Scrive ricorsivamente la descrizione della superclasse fino a quando non trova java.lang.object .
3. Una volta terminata la scrittura delle informazioni sui metadati, inizia con i dati effettivi associati all'istanza. Ma questa volta, inizia dalla superclasse più in alto.
4. Scrive in modo ricorsivo i dati associati all'istanza, a partire dalla superclasse minima alla classe più derivata.
Cose da tenere a mente:
I campi statici in una classe non possono essere serializzati.
public class A implements Serializable{
String s;
static String staticString = "I won't be serializable";
}
Se il serialversionuid è diverso nella classe read genererà InvalidClassException
un'eccezione.
Se una classe implementa serializzabile, anche tutte le sue sottoclassi saranno serializzabili.
public class A implements Serializable {....};
public class B extends A{...} //also Serializable
Se una classe ha un riferimento di un'altra classe, tutti i riferimenti devono essere serializzabili altrimenti il processo di serializzazione non verrà eseguito. In tal caso, NotSerializableException viene generato in fase di esecuzione.
Per esempio:
public class B{
String s,
A a; // class A needs to be serializable i.e. it must implement Serializable
}
serialVersionUID
è diverso, verrà lanciato un InvalidClassException
, non un ClassCastException
. Non è necessario sprecare tutto quello spazio rispettando il serialVersionUID
calcolo. La documentazione viene citata, a una lunghezza eccessiva, ma non collegata o citata correttamente. Troppa lanugine qui e troppi errori.
La serializzazione è il processo di conversione dello stato di un oggetto in bit in modo che possa essere memorizzato su un disco rigido. Quando si deserializza lo stesso oggetto, manterrà il suo stato in seguito. Ti consente di ricreare oggetti senza dover salvare le proprietà degli oggetti a mano.
Serializzazione di oggetti Java
Serialization
è un meccanismo per trasformare un grafico di oggetti Java in una matrice di byte per storage ( to disk file
) o transmission ( across a network
), quindi utilizzando la deserializzazione possiamo ripristinare il grafico degli oggetti. I grafici degli oggetti vengono ripristinati correttamente utilizzando un meccanismo di condivisione di riferimento. Ma prima di archiviare, controlla se serialVersionUID da input-file / network e .class serialVersionUID sono uguali. Altrimenti, lancia a java.io.InvalidClassException
.
Ogni classe con versione deve identificare la versione della classe originale per la quale è in grado di scrivere flussi e dalla quale può leggere. Ad esempio, una classe con versione deve dichiarare:
serialVersionUID Sintassi
// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L; private static final long serialVersionUID = 3487495895819393L;
serialVersionUID è essenziale per il processo di serializzazione. Ma è facoltativo per lo sviluppatore aggiungerlo nel file sorgente Java. Se un serialVersionUID non è incluso, il runtime di serializzazione genererà un serialVersionUID e lo assocerà alla classe. L'oggetto serializzato conterrà questo serialVersionUID insieme ad altri dati.
Nota : si consiglia vivamente che tutte le classi serializzabili dichiarino esplicitamente un serialVersionUID since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations
e possano quindi causare conflitti imprevisti serialVersionUID durante la deserializzazione, causando il fallimento della deserializzazione.
Ispezione delle classi serializzabili
Un oggetto Java è solo serializzabile. se una classe o una delle sue superclasse implementa l' interfaccia java.io.Serializable o la sua interfaccia secondaria, java.io.Externalizable .
Una classe deve implementare l' interfaccia java.io.Serializable per serializzare correttamente il suo oggetto. Serializable è un'interfaccia marker e utilizzata per informare il compilatore che alla classe che lo implementa deve essere aggiunto un comportamento serializzabile. Qui Java Virtual Machine (JVM) è responsabile della sua serializzazione automatica.
parola chiave transitoria:
java.io.Serializable interface
Durante la serializzazione di un oggetto, se non vogliamo che determinati membri dei dati dell'oggetto vengano serializzati, possiamo usare il modificatore transitorio. La parola chiave temporanea impedirà la serializzazione del membro in questione.
- I campi dichiarati come transitori o statici vengono ignorati dal processo di serializzazione.
+--------------+--------+-------------------------------------+ | Flag Name | Value | Interpretation | +--------------+--------+-------------------------------------+ | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.| +--------------+--------+-------------------------------------+ |ACC_TRANSIENT | 0x0080 | Declared transient; not written or | | | | read by a persistent object manager.| +--------------+--------+-------------------------------------+
class Employee implements Serializable {
private static final long serialVersionUID = 2L;
static int id;
int eno;
String name;
transient String password; // Using transient keyword means its not going to be Serialized.
}
L'implementazione dell'interfaccia Externalizable consente all'oggetto di assumere il controllo completo sul contenuto e sul formato della forma serializzata dell'oggetto. I metodi dell'interfaccia Externalizable, writeExternal e readExternal, vengono chiamati per salvare e ripristinare lo stato degli oggetti. Se implementati da una classe, possono scrivere e leggere il proprio stato usando tutti i metodi di ObjectOutput e ObjectInput. È responsabilità degli oggetti gestire qualsiasi versione che si verifica.
class Emp implements Externalizable {
int eno;
String name;
transient String password; // No use of transient, we need to take care of write and read.
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(eno);
out.writeUTF(name);
//out.writeUTF(password);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.eno = in.readInt();
this.name = in.readUTF();
//this.password = in.readUTF(); // java.io.EOFException
}
}
Solo gli oggetti che supportano l'interfaccia java.io.Serializable o java.io.Externalizable possono essere written to
/read from
stream. La classe di ogni oggetto serializzabile viene codificata includendo il nome e la firma della classe, i valori dei campi e delle matrici dell'oggetto e la chiusura di qualsiasi altro oggetto a cui fanno riferimento gli oggetti iniziali.
Esempio serializzabile per file
public class SerializationDemo {
static String fileName = "D:/serializable_file.ser";
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
Employee emp = new Employee( );
Employee.id = 1; // Can not Serialize Class data.
emp.eno = 77;
emp.name = "Yash";
emp.password = "confidential";
objects_WriteRead(emp, fileName);
Emp e = new Emp( );
e.eno = 77;
e.name = "Yash";
e.password = "confidential";
objects_WriteRead_External(e, fileName);
/*String stubHost = "127.0.0.1";
Integer anyFreePort = 7777;
socketRead(anyFreePort); //Thread1
socketWrite(emp, stubHost, anyFreePort); //Thread2*/
}
public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
objectOut.writeObject( obj );
objectOut.close();
fos.close();
System.out.println("Data Stored in to a file");
try {
FileInputStream fis = new FileInputStream( new File( serFilename ) );
ObjectInputStream ois = new ObjectInputStream( fis );
Object readObject;
readObject = ois.readObject();
String calssName = readObject.getClass().getName();
System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException
Employee emp = (Employee) readObject;
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
FileOutputStream fos = new FileOutputStream(new File( serFilename ));
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
obj.writeExternal( objectOut );
objectOut.flush();
fos.close();
System.out.println("Data Stored in to a file");
try {
// create a new instance and read the assign the contents from stream.
Emp emp = new Emp();
FileInputStream fis = new FileInputStream(new File( serFilename ));
ObjectInputStream ois = new ObjectInputStream( fis );
emp.readExternal(ois);
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Esempio serializzabile su rete
Distribuire lo stato dell'oggetto su diversi spazi indirizzo, sia in processi diversi sullo stesso computer, sia in più computer collegati tramite una rete, ma che lavorano insieme condividendo dati e invocando metodi.
/**
* Creates a stream socket and connects it to the specified port number on the named host.
*/
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
try { // CLIENT - Stub[marshalling]
Socket client = new Socket(stubHost, anyFreePort);
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(objectToSend);
out.flush();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Creates a server socket, bound to the specified port.
public static void socketRead( Integer anyFreePort ) {
try { // SERVER - Stub[unmarshalling ]
ServerSocket serverSocket = new ServerSocket( anyFreePort );
System.out.println("Server serves on port and waiting for a client to communicate");
/*System.in.read();
System.in.read();*/
Socket socket = serverSocket.accept();
System.out.println("Client request to communicate on port server accepts it.");
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Employee objectReceived = (Employee) in.readObject();
System.out.println("Server Obj : "+ objectReceived.name );
socket.close();
serverSocket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@vedere
JVM to JVM
La serializzazione è il processo di salvataggio di un oggetto in un supporto di memorizzazione (come un file o un buffer di memoria) o di trasmetterlo su una connessione di rete in forma binaria. Gli oggetti serializzati sono indipendenti dalla JVM e possono essere nuovamente serializzati da qualsiasi JVM. In questo caso lo stato degli oggetti java "in memoria" viene convertito in un flusso di byte. Questo tipo di file non può essere compreso dall'utente. Si tratta di un tipo speciale di oggetto, ovvero riutilizzato dalla JVM (Java Virtual Machine). Questo processo di serializzazione di un oggetto è anche chiamato sgonfiamento o marshalling di un oggetto.
L'oggetto da serializzare deve implementare l' java.io.Serializable
interfaccia. Il meccanismo di serializzazione predefinito per un oggetto scrive la classe dell'oggetto, la firma della classe e i valori di tutti i campi non transitori e non statici.
class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,
ObjectOutput
interfaccia estende l' DataOutput
interfaccia e aggiunge metodi per serializzare oggetti e scrivere byte nel file. L' ObjectOutputStream
estensione java.io.OutputStream
e implementa l' ObjectOutput
interfaccia. Serializza oggetti, matrici e altri valori su un flusso. Quindi il costruttore di ObjectOutputStream
è scritto come:
ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));
Il codice sopra è stato usato per creare l'istanza della ObjectOutput
classe con il ObjectOutputStream( )
costruttore che accetta l'istanza di FileOuputStream
come parametro.
L' ObjectOutput
interfaccia viene utilizzata implementando la ObjectOutputStream
classe. Il ObjectOutputStream
è costruito per serializzare l'oggetto.
Deserializzare un oggetto in Java
L'operazione opposta della serializzazione si chiama deserializzazione, ovvero estrarre i dati da una serie di byte è conosciuta come deserializzazione, che è anche chiamata inflazione o smascheramento.
ObjectInputStream
estende java.io.InputStream
e implementa l' ObjectInput
interfaccia. Deserializza oggetti, matrici e altri valori da un flusso di input. Quindi il costruttore di ObjectInputStream
è scritto come:
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));
Il codice sopra del programma crea l'istanza della ObjectInputStream
classe per deserializzare quel file che era stato serializzato dalla ObjectInputStream
classe. Il codice sopra crea l'istanza usando l'istanza della FileInputStream
classe che contiene l'oggetto file specificato che deve essere deserializzato perché il ObjectInputStream()
costruttore ha bisogno del flusso di input.
La serializzazione è il processo di trasformazione di un oggetto Java in array di byte e quindi di nuovo in oggetto con lo stato conservato. Utile per varie cose come l'invio di oggetti in rete o la memorizzazione nella cache di oggetti sul disco.
Leggi di più da questo breve articolo che spiega abbastanza bene la parte di programmazione del processo e poi passa a javadoc serializzabile . Potresti anche essere interessato a leggere questa domanda correlata .
Restituisce il file come oggetto: http://www.tutorialspoint.com/java/java_serialization.htm
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
| * | Serializzazione di una classe: conversione di un oggetto in byte e byte nuovamente in oggetto (Deserializzazione).
class NamCls implements Serializable
{
int NumVar;
String NamVar;
}
| => La serializzazione di oggetti è un processo di conversione dello stato di un oggetto in vapore di byte.
| => La deserializzazione di oggetti è il processo per ottenere lo stato di un oggetto e memorizzarlo in un oggetto (java.lang.Object).
| => Un oggetto Java è serializzabile solo se la sua classe o una delle sue superclasse
| => I campi statici in una classe non possono essere serializzati.
class NamCls implements Serializable
{
int NumVar;
static String NamVar = "I won't be serializable";;
}
| => Se non si desidera serializzare una variabile di una classe, utilizzare una parola chiave temporanea
class NamCls implements Serializable
{
int NumVar;
transient String NamVar;
}
| => Se una classe implementa serializzabile, anche tutte le sue sottoclassi saranno serializzabili.
| => Se una classe ha un riferimento di un'altra classe, tutti i riferimenti devono essere serializzabili altrimenti il processo di serializzazione non verrà eseguito. In tal caso,
NotSerializableException viene generato in fase di esecuzione.
Offrirò un'analogia per aiutare potenzialmente a consolidare lo scopo concettuale / la praticità della serializzazione / deserializzazione degli oggetti .
Immagino la serializzazione / deserializzazione degli oggetti nel contesto del tentativo di spostare un oggetto attraverso una tempesta. L'oggetto è essenzialmente "decomposto" o serializzato in versioni più modulari di se stesso - in questo caso, una serie di byte - per consentire effettivamente il passaggio attraverso un supporto. In senso computazionale, potremmo vedere il percorso percorso dai byte attraverso la tempesta come simile ai byte che viaggiano attraverso una rete. Trasmutiamo il nostro oggetto per conformarci a una modalità di trasporto o formato più desiderabile. L'oggetto serializzato viene in genere archiviato in un file binario che può essere successivamente letto, scritto o entrambi.
Forse una volta che il nostro oggetto è in grado di scivolare attraverso il drain come una serie decomposta di byte, potremmo voler archiviare quella rappresentazione dell'oggetto come dati binari all'interno di un database o di un disco rigido. Il principale takeaway però è che con la serializzazione / deserializzazione, abbiamo la possibilità di lasciare che il nostro oggetto rimanga nella sua forma binaria dopo essere stato serializzato, o "recuperare" la forma originale dell'oggetto eseguendo la deserializzazione.