应用场景:
rpc框架中数据传输
常见的序列化方式:
Java原生序列化、xml、json、hessian、protobuffer、avro...
以下演示Java原生序列化方式:
Java原生序列化缺点:
1.序列化数据比较大
2.无法跨语言传输
序列化前提 必须实现Serializable接口
public class User implements Serializable {
private static final long serialVersionUID = -2155397842970858163L;
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.io.*;
public class SerializableDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user=new User();
user.setName("cc");
user.setAge(18);
//流的方式
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(user);
byte[] bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
User user1= (User) objectInputStream.readObject();
System.out.println(user1);//User{name='cc', age=18}
}
}
原理分析
-
serialVersionUID 相当于该类的指纹 如果序列化与反序列化的时候,该值不对,会抛出InvalidClassException
-
transient关键字
user上加上: private transient String sex; public static void main(String[] args) throws IOException, ClassNotFoundException { User user=new User(); user.setName("cc"); user.setSex("男"); user.setAge(18); ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(user); byte[] bytes = byteArrayOutputStream.toByteArray(); ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream); User user1= (User) objectInputStream.readObject(); System.out.println(user1);//User{name='cc', age=18, sex='null'} } 会发现sex字段无法被序列化 解决方案: 在user类中增加: private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); sex=(String) in.readObject(); } private void writeObject(ObjectOutputStream out)throws IOException { out.defaultWriteObject(); out.writeObject(sex); } 原因:Java序列化时会默认调用readObject和writeObject方法 此时再次执行main方法: 执行结果:User{name='cc', age=18, sex='男'}