java 的serializable 理解和总结

目录

serializable 理解和总结

序列化是做什么的

什么情况下需要序列化

注意事项

为什么java需要进行序列化

transient关键字


序列化是做什么的

   对象的生命周期常随着生成该对象的程序的终止而终止,有时候需要把内存中的各种对象状态

(也就是实例变量,不是方法)保存下来并且可以在需要时再将对象恢复.虽然你可以用你自己的

方法保存对象的状态,但是java提供了一种应该比我们好的保存对象状态的机制,那就是序列化

 

       什么情况下需要序列化?
             1.当你想要把内存中的对象状态保存到一个文件中或者数据中的时候
             2.当你想用套接字在网络上传送对象的时候
             3.当你想要通过RMI传输对象的时候

 

      当对一个对象实现序列化时,究竟发生了什么?
            在没有序列化前,每个保存在堆中的对象都有相应的状态,即实例变量

比如:
	Person p = new Person();

	p.setName("lisi");
	p.setAge(23);

	当通过下面的代码序列化之后,Person对象中的name和age实例变量的值("lisi",23)都被保存到p.ser文件中,这样以后又可以把它从文件中读取出来,重新在堆中创建原来的对象.当然保存时不仅仅是保存对象的实例变量的值
	JVM还要保存一些别的特殊信息.

	FileOutputStream fs = new FileOutputStream("p.ser");  
	ObjectOutputStream os = new ObjectOutputStream(fs);  
	os.writeObject(p);  
	import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Person implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7970005053591210082L;
	
	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;
	}
	
	public static void main(String[] args) {
		Person p = new Person();
		p.setName("yinlele");
		p.setAge(23);
		
		try {
			FileOutputStream fis = new FileOutputStream("p.ser");
			ObjectOutputStream oos = new ObjectOutputStream(fis);
			oos.writeObject(p);
			oos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

打开p.ser文件之后的信息

注意事项:
    1).序列化时,只对对象的状态保存,而不管对象的方法
    2).当一个父类实现序列化时,子类自动序列化,不需要显式实现Serializable接口
    3).当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象序列化.
    4).并非所有的对象都可以序列化.(遇到在补充)

 

为什么java需要进行序列化

    java序列化:一特定的方式对类实例的瞬时状态进行编码保存的一种操作.
    序列化作用的对象是类的实例,对实例进行序列化,就是保存实例当前在内存中的状态,包括实例的每一个属性的值和引用

    反序列化,是将序列化的编码解码成类实例的瞬时状态


    序列化就是为了保存java类的对象状态.保存这个状态的作用主要用于不同jvm之间进行类实例间的共享,在ORMaping中的缓存机制,进行缓存同步时,便是常见的java序列化的应用之一.在进行远程方法调用,远程过程调用时,采用序列化对象的传输也是一种应用...当你想从一个jvm中调用另一个jvm的对象时,你就可以考虑使用序列化了.


    总之:序列化的作用就是为了不同jvm之间共享实例对象的一种解决方案,由java提供此机制,效率之高,
         是其他解决方案无法比拟的.
 

 

transient关键字
        经常在实现了 Serializable接口的类中能看见transient关键字。这个关键字并不常见。 transient关键字的作用是:阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。

        当某些变量不想被序列化,同是又不适合使用static关键字声明,那么此时就需要用transient关键字来声明该变量。

    例如用 transient关键字 修饰age变量

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Person implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7970005053591210082L;
	
	private String name ;
	transient private Integer age;
	
	private Gender gender;
	
	public Person() {
		super();
	}
	public Person(String name, Integer age, Gender gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public Gender getGender() {
		return gender;
	}
	public void setGender(Gender gender) {
		this.gender = gender;
	}
	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() {
		StringBuilder builder = new StringBuilder();
		builder.append("Person [name=");
		builder.append(name);
		builder.append(", age=");
		builder.append(age);
		builder.append(", gender=");
		builder.append(gender);
		builder.append("]");
		return builder.toString();
	}
	public static void main(String[] args) throws Exception {
		File file = new File("person.out");
        ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
        Person person = new Person("yinlele", 23, Gender.MALE);
        oout.writeObject(person);
        oout.close();

        ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
        Object newPerson = oin.readObject(); // 没有强制转换到Person类型
        oin.close();
        System.out.println(newPerson);
        //Person [name=yinlele, age=23, gender=MALE] 不加transient
        
        //Person [name=yinlele, age=null, gender=MALE]//加上 transient

	}

以上只是为自己以后用到的时候方便,做个记录

  • 14
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的Serializable是一个接口,用于实现对象的序列化和反序列化。当一个类实现了Serializable接口时,它的对象可以被转换为字节流,以便在网络上传输或者保存到文件中。同时,这些字节流也可以被反序列化为对象,以便在程序中重新使用。 以下是一个示例,演示了如何在Java中使用Serializable接口进行对象的序列化和反序列化: ```java import java.io.*; public class SerializationDemo { public static void main(String[] args) { // 创建一个Person对象 Person person = new Person(1, "John"); // 将Person对象序列化为字节流 try { FileOutputStream fileOut = new FileOutputStream("person.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(person); out.close(); fileOut.close(); System.out.println("Person对象已序列化并保存到person.ser文件中"); } catch (IOException e) { e.printStackTrace(); } // 从字节流中反序列化Person对象 try { FileInputStream fileIn = new FileInputStream("person.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); Person deserializedPerson = (Person) in.readObject(); in.close(); fileIn.close(); System.out.println("从person.ser文件中反序列化得到的Person对象为:" + deserializedPerson); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } ``` 请注意,要使一个类可序列化,需要满足以下条件: 1. 类必须实现Serializable接口。 2. 所有非静态和非瞬态的成员变量都必须是可序列化的。 3. 如果父类实现了Serializable接口,子类也会自动实现Serializable接口。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值