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();
}
}
ObjectInputStream oos = new ObjectInputStream(
new FileInputStream( new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();
Serialization是一种将Java对象图转换为用于存储(to disk file)或传输(across a network)的字节数组的机制,然后通过使用反序列化我们可以恢复对象图。
使用引用共享机制正确地恢复对象的图。但是在存储之前,请检查input-file/network中的serialVersionUID和.class文件中的serialVersionUID是否相同。如果不是,则抛出java.io.InvalidClassException。 < / p >
每个版本化的类必须确定它能够为其写入流和从中读取流的原始类版本。例如,一个有版本控制的类必须声明:
serialVersionUID的语法
// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;
请注意——强烈建议所有可序列化类显式声明一个serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations,这样会在反序列化期间导致意外的serialVersionUID冲突,导致反序列化失败。
+--------------+--------+-------------------------------------+
| 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.
}
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
}
}
/**
* 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();
}
}
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]
public class A implements Serializable{
String s;
static String staticString = "I won't be serializable";
}
If the serialversionuid is different in the read class it will throw a InvalidClassException exception.
If a class implements serializable then all its sub classes will also be serializable.
public class A implements Serializable {....};
public class B extends A{...} //also Serializable
If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.
Eg:
public class B{
String s,
A a; // class A needs to be serializable i.e. it must implement Serializable
}
我想象< em >对象序列化/反序列化< / em >在试图移动一个物体通过雨水沟的上下文中。对象本质上被“分解”或序列化分解为自身的更模块化的版本——在本例中是字节序列——以便有效地通过介质。在计算的意义上,我们可以将字节通过排水沟的路径视为类似于字节通过网络的路径。我们正在改变我们的对象,以符合更理想的运输方式或格式。序列化的对象通常存储在二进制文件中,以后可以对该文件进行读、写或同时进行读、写。