java序列化怎么用

序列化是什么:

序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。

序列化有什么特点:

如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。

什么时候使用序列化:

一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
二:对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。

 

1.Serializable方法

package cn.entity;


import java.io.Serializable;
 
public class Man implements Serializable {
	
	//serialization 的key,相同的Key可以相互序列化和反序列化
    private static final long serialVersionUID = 1L;
 
    private String username;
    private String password;
 
    public Man(String username, String password) {
        this.username = username;
        this.password = password;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
}

package cn.entity;
import java.io.Serializable;
 
public class Person implements Serializable {
	
	//serialization 的key,相同的Key可以相互序列化和反序列化
    private static final long serialVersionUID = 1L;
    
    private Man man;
    private String username;
    private transient int age;	//用transient关键字标记的成员变量不参与序列化过程。
    
    public Person() {
        System.out.println("person constru");
    }
    
    public Person(Man man, String username, int age) {
        this.man = man;
        this.username = username;
        this.age = age;
    }
 
    public Man getMan() {
        return man;
    }
    public void setMan(Man man) {
        this.man = man;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

 

2.Externalizable用法

package cn.entity;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
 
public class User implements Externalizable {
	
    private String user;
    
    private int age;
 
    public String getUser() {
        return user;
    }
 
    public int getAge() {
        return age;
    }
 
    public User() {
        System.out.println("user constructor.");
    }
 
    public User(String user, int age) {
        System.out.println("user constructor two.");
        this.user = user;
        this.age = age;
    }
 
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        System.out.println("read external.");
        user = (String) in.readObject();
        age = in.readInt();
    }
 
    public void writeExternal(ObjectOutput out) throws IOException {
        System.out.println("write external.");
        out.writeObject(user);
        out.writeInt(age);
    }
}

3.测试

package cn.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.junit.Test;

import cn.entity.Man;
import cn.entity.Person;
import cn.entity.User;

public class ManTest {
	
	//序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。
	
	@Test
	// Serializable:把对象序列化
	public  void writeSerializableObject() {
	    try {
	        Man man = new Man("huhx", "123456");
	        Person person = new Person(man, "刘力", 21);
	        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("F:/output.txt"));
	        objectOutputStream.writeObject("string");
	        objectOutputStream.writeObject(person);
	        objectOutputStream.close();
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}
	
	@Test
	// Serializable:反序列化对象
	public  void readSerializableObject() {
	    try {
	        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("F:/output.txt"));
	        String string = (String) objectInputStream.readObject();
	        Person person = (Person) objectInputStream.readObject();
	        objectInputStream.close();
	        System.out.println(string + ", age: " + person.getAge() + ", man username: " + person.getMan().getUsername());
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	}
	
	//在Person类中包含Man的引用,当Person被序列化的时候,从结果可以知道Man也被序列化了
	//writeObject方法可以传入String,是因为String首先是一个类,其次它也是实现了Serializable接口的
	//Person类中的age字段是transient(英文:暂态),从打印结果可以看到,序列化Person person = new Person(man, "刘力", 21)对象时,age没有进行序列化。如果transient修饰的Object类型的,那么打印的结果将会是null
	
	@Test
	// Externalizable的序列化对象
	public  void writeExternalizableObject() {
	    User user = new User("huhx", 22);
	    try {
	        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("F:/Externalizable.txt"));
	        objectOutputStream.writeObject(user);
	        objectOutputStream.close();
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}
	
	@Test
	// Externalizable的反序列化对象
	public  void readExternalizableObject() {
	    try {
	        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("F:/Externalizable.txt"));
	        User user = (User) objectInputStream.readObject();
	        objectInputStream.close();
	        System.out.println("name: " + user.getUser() + ", age: " + user.getAge());
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	}

	
	
}

1、Serializable序列化时不会调用默认的构造器,而Externalizable序列化时会调用默认构造器的!!! 
2、Serializable:一个对象想要被序列化,那么它的类就要实现 此接口,这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。 
Externalizable:他是Serializable接口的子类,有时我们不希望序列化那么多,可以使用这个接口,这个接口的writeExternal()和readExternal()方法可以指定序列化哪些属性。

注意: 
对象的序列化并不属于新的Reader和Writer层次结构的一部分,而是沿用老式的InputStream和OutputStream结构,在某些情况下,不得不混合使用两种类型的层次结构。

恢复了一个反序列化的对象后,如果想对其做更多的事情(对象.getClass().xxx),必须保证JVM能在本地类路径或者因特网的其他什么地方找到相关的.class文件。 
恢复对象的默认构建器必须是public的,否则会抛异常。

由于Externalizable对象默认时不保存对象的任何字段,所以transient关键字只能伴随Serializable使用,虽然Externalizable对象中使用transient关键字也不报错,但不起任何作用。 
3、把transient修饰的字段序列化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值