java序列化本身存在的問題
上代碼:
環境 idea jdk1.8 maven
生成一個類的serialVersionUID,idea提供快捷鍵
也可以自己手動指定UID
Person對象,之後序列化的例子都會使用
public class Person implements Serializable {
private static final long serialVersionUID = -7290089721196747652L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age
'}';
}
}
public class SerializeDemo {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
DeSerializePerson();
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));
Person person=new Person();
person.setName("c羅");
person.setAge(32);
oo.writeObject(person);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
System.out.println(person);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
在剛纔的Person對象中增加一個靜態變量字段height
public class Person implements Serializable {
private static final long serialVersionUID = -7290089721196747652L;
public static int height = 178;
public static void main(String [] args){
//序列化操作
SerializePerson();
Person.height=180;
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person.height);
}
結果打印的不是序列化對象的height=178
private transient String sex;
public class SerializeDemo3 {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person);
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person"))); //默認在根目錄
Person person=new Person();
person.setName("c羅");
person.setAge(32);
person.setSex("man");
oo.writeObject(person);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Person DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
return person;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
transient修飾的sex不參與序列化
public class SuperUser {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SuperUser{" +
"name='" + name + '\'' +
'}';
}
}
public class User extends SuperUser implements Serializable {
private static final long serialVersionUID = -1290089721196747652L;
@Override
public String toString() {
return "User{} " + super.toString();
}
}
public class MyTest {
public static void main(String [] args){
//序列化操作
SerializeUser();
//反序列化操作
User user=DeSerializeUser();
System.out.println(user);
}
public static void SerializeUser(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("user"))); //默認在根目錄
User user=new User();
user.setName("c羅");
oo.writeObject(user);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static User DeSerializeUser(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("user")));
User user = (User)oi.readObject();
return user;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class SuperUser implements Serializable{
public class SerializeDemo4 {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person);
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person"))); //默認在根目錄
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person=new Person();
person.setName("c羅");
person.setAge(32);
person.setSex("man");
oo.writeObject(person);
oo.flush();
System.out.println("第一次序列化成功,長度爲"+new File("person").length());
Person person1=(Person)oi.readObject();
oo.writeObject(person);
oo.flush();
System.out.println("第二次序列化成功,長度爲"+new File("person").length());
Person person2=(Person)oi.readObject();
oo.close();
System.out.println(person1==person2);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Person DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
return person;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class Student implements Serializable {
private static final long serialVersionUID = -3330089721196747652L;
private String name;
private int age;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
//序列化的方式實現深度克隆
public Object deepClone() throws Exception{
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return ois.readObject();
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
}
public class Teacher implements Serializable {
private static final long serialVersionUID = -4330089021196747652L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
public class cloneDemo {
public static void main(String []args)throws Exception{
Teacher teacher = new Teacher();
teacher.setName("a");
Student student=new Student();
student.setName("zhangsan");
student.setAge(18);
student.setTeacher(teacher);
System.out.println(student);
Student s = (Student)student.deepClone();
System.out.println(s);
System.out.println("student==s : "+(student==s)); //返回false表示不是指向同一個對象,即深度克隆
System.out.println("student.equals(s) : "+(student.equals(s)));
//修改s的老師的引用對象的屬性值
s.getTeacher().setName("b");
System.out.println(student);
System.out.println(s);
}
}
序列化技術所需依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pers.wmx.demo</groupId>
<artifactId>Serialize</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- spring默認的-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<!-- 百度封裝的 -->
<dependency>
<groupId>com.baidu</groupId>
<artifactId>jprotobuf</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
</dependencies>
</project>
上代碼
public class JsonDemo {
private static Person init(){
Person person = new Person();
person.setName("梅西");
person.setAge(30);
return person;
}
public static void main(String []args)throws Exception{
System.out.println("JackSon序列化...");
excuteWithJack();
System.out.println("FastJson序列化...");
excuteWithFastJson();
System.out.println("Protobuf序列化...");
excuteWithProtobuf();
System.out.println("Hessian序列化...");
excuteWithHessian();
}
//使用jackson序列化
private static void excuteWithJack() throws Exception{
Person person=init();
ObjectMapper mapper = new ObjectMapper();
byte [] writeBytes=null;
Long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
writeBytes=mapper.writeValueAsBytes(person);
}
System.out.println("序列化用時"+(System.currentTimeMillis()-start)+"ms");
System.out.println(writeBytes.length);
Person person1 = mapper.readValue(writeBytes,Person.class);
System.out.println(person1);
}
//使用fastjson序列化
private static void excuteWithFastJson() throws Exception{
Person person=init();
String text=null;
Long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
text=JSON.toJSONString(person);
}
System.out.println("序列化用時"+(System.currentTimeMillis()-start)+"ms");
System.out.println("text "+text);
System.out.println(text.getBytes().length);
Person person1 = JSON.parseObject(text,Person.class);
System.out.println("person1 "+person1);
}
//使用Protobuf序列化 性能高 字節數小,適合網絡傳輸
private static void excuteWithProtobuf() throws Exception{
Person person=init();
Codec<Person> personCodec =ProtobufProxy.create(Person.class,false);
Long start=System.currentTimeMillis();
byte[] bytes=null;
for (int i = 0; i <10000 ; i++) {
bytes=personCodec.encode(person);
}
System.out.println("序列化用時"+(System.currentTimeMillis()-start)+"ms");
System.out.println(bytes.length);
Person person1 = personCodec.decode(bytes);
System.out.println(person1);
}
//使用Hessian序列化
private static void excuteWithHessian() throws Exception{
Person person=init();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
HessianOutput ho=new HessianOutput(baos);
Long start=System.currentTimeMillis();
for (int i = 0; i <10000 ; i++) {
ho.writeObject(person);
}
System.out.println("序列化用時"+(System.currentTimeMillis()-start)+"ms");
System.out.println(baos.toByteArray().length);
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
HessianInput hi=new HessianInput(bais);
Person person1 = (Person)hi.readObject();
System.out.println(person1);
}
}