您的位置:首页 > 其它

序列化Serialization和transient关键字小结

2017-10-05 00:00 706 查看
序列化和transient关键字应该属于java中较高级的话题,笔者(ymh)今天花一点时间小结一些这部分知识,希望能给初学者一些帮助。若有错误希望指出,学无止境。转载请注明出处!

什么是序列化?

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

如何实现序列化?

java中要想一个类的实例能够被序列化,则该类可以实现Serializable接口,这是一个空接口,其中并没有任何需要实现的方法,仅用来在编译时让编译器标识该类的实例可被序列化,实现Serializable接口的类的实例属性将自动参与序列化过程。

另外,java类也可以实现Externalizable接口,该接口是Serializable接口的子接口,有两个抽象方法:



实现Externalizable接口的java类需要writeExternal方法中明确指定哪些属性要参与序列化过程。

transient关键字的用途?

transient关键字只能用于修饰变量,不能修饰方法和类。若一个类中有些属性需要被序列化,应先实现Serializable接口,而有一些属性包含敏感信息,如密码、银行卡号等,这些信息若不想被序列化,可以用transient关键字修饰。被transient修饰的属性将不参与序列化过程。

Serializable接口配合transient关键字使用案例:

public class SerializationDemo {

final static class Person implements Serializable{
private transient String id; //transient修饰的实例属性
private String name;
private static int count;
private static transient String desc; //transient修饰的类属性
public Person(){}
public Person(String id,String name,int count1,String desc1)
{
this.id=id;
this.name=name;
count=count1;
desc=desc1;
}
}

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
System.out.println("序列化:将对象写入文件");
Person person=new Person(UUID.randomUUID().toString(), "张三", 11, "我是张三");
System.out.println("transient修饰的实例属性:"+person.id);
System.out.println("普通实例属性:"+person.name);
System.out.println("普通类属性:"+person.count);
System.out.println("transient修饰的类属性:"+person.desc);
//序列化
File objectFile=new File("f:/mm.txt");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(objectFile));
oos.writeObject(person);
oos.close();
person=null;
 
3ff0
;//反序列化
System.out.println("反序列化:从文件中读取对象");
Person.count=22;
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(objectFile));
person=(Person) ois.readObject();
System.out.println("transient修饰的实例属性:"+person.id);
System.out.println("普通实例属性:"+person.name);
System.out.println("普通类属性:"+person.count);
System.out.println("transient修饰的类属性:"+person.desc);
ois.close();
}

}

输出结果:



结论:

1、对于实例属性来说,被transient修饰的实例属性将不会参与序列化。

2、对于类属性来说,无论类属性是否被transient关键字修饰,类属性都不会参加序列化过程。

可以这样理解:序列化是针对对象的操作过程,而类属性是属于类的一部分,不属于某个具体的实例,因此类属性不参与序列化。

上面测试代码也很好的佐证了这一观点,因若类属性能够被序列化,则反序列化读取到的类属性值应该与序列化时写入的类属性值一致,但代码中反序列化前修改了类属性值,反序列化读取到的该类属性值跟着变化,说明该类属性的值并不是从反序列化的过程中读取到的,实际上是从JVM的方法区中读取的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: