4)transient关键字
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
分析ArrayList源码中序列化和反序列化的问题
ArrayList源码分析关于序列化的问题
比如说数组它不一定放满了,所以说只要对那些有内容的元素自己去序列化
魔方ArrayList自己进行序列化的方法
transient的作用,这是一种提高
序列化和反序列化的读写操作:
ObjectInputStream:反序列化:将byte转换成Object,用readObject方法
ObjectOutputStream:序列化:将Object转成byte,用writeObject方法
前提:对象实现Serialization序列化接口
transient:关键字:用来修饰属性,如图
1,表示该属性元素不会进行JVM默认的序化
2,不进行默认的序列化操作,但是可以自己单独写序列化操作,场景:ArrayList(底层对数组元素进行序列化和反序列化操作,提高性能)
private transient int stuage
该元素不会进行默认的序列化,但也可以自行完成这个元素的序列化
ArrayList中序列化和反序列化:对于数组中没放满的元素不需要序列化。只对有效元素序列化,提高性能,所以需要手动序列化。
transient关键字:该元素不会进行jvm默认的序列化
序列化类实现方法签名
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{
s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作
s.writeInt(stuage);//自己完成stuage的序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException,ClassNotFoundException{
s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作
this.stuage=s.readInt();//自己完成stuae的反序列化操作
}
(4)transient 关键字
private transient int stuage; //该元素不会进行jvm默认的序列化
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{}
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException,ClassNotFoundException{}
private transient int Age;
//可以不让虚拟机默认序列化,但是还是可以序列化
//序列化操作
private void writeObject(java.io.ObjectOutputStream s){
throws java.io.IOException{
s.defaultWriteObject();
s.writeInt();
}
//反序列化类似//反序列化
对象的序列化和反序列化
transient关键字:修饰的变量在被序列化是会被jvm默认跳过。但仍然可以通过其他方式完成对该变量的序列化,参照ArrayList源码。
private transient int stuage; //被transient修饰时,默认不会被序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm(虚拟机)能默认序列化的元素进行序列化操作
s.writeInt(stuage);//自己完成stuage的序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();//把jvm(虚拟机)能默认反序列化的元素进行反序列化操作
this.stuage=s.readInt();//自己完成stuage的反序列化操作
transient有些情况下能够帮助提高性能
分析ArrayList可以发现,ArrayList底层虽然是一个数组,但是数组不一定放满了,没有放满的数组元素是不需要序列化的,所以自己来完成有效元素的序列化和反序列化。所以能够提升性能
transient关键字
在修饰某些变量时,这个变量不会被系统默认序列化,可以用其他类型来单独进行序列化。在反序列化时也必须进行相同类型的反序列化操作。
//序列化
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{
s.defaultwriteObject();//将无trensient关键字修饰的元素进行系统默认类型的序列化操作。
s.writeInt();//将transient关键字修饰的元素进行自定义的序列化操作。
}
//反序列化
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException{
S.defaultReadObject();//将虚拟机默认反序列化的元素进行反序列化操作。
this.stuage=s.readInt();//加了transient关键字的元素进行对应的序列化类型的反序列化。
}
transient关键字的作用在某些情况下能提高存储性能。
transient关键字修饰属性不会进行默认序列化或反序列化,但可以自己进行(反)序列化
4) transient关键字
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{
s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作
s.writeInt(stuage);//自己完成stuage的序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException,ClassNotFoundException{
s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作
this.stuage=s.readInt();//自己完成stuae的反序列化操作
}
transient关键字的作用: 分析ArrayList源码中序列化和反序列化的问题
序列化有什么用处
数组可能没放满,自己序列化数组的有效元素。提高性能
4)transient关键字
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{ }
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{ }
分析ArrayList源码中序列化和反序列化的问题
使用transient关键字不做jvm默认的序列化,可自己完成该元素的序列化
//重要语句 public class Student implements Serializable { private transient int stuage; private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject();// 把jvm能默认序列化的元素进行序列化操作 s.writeInt(stuage);// 自己完成stuage的序列化 } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject();// 把jvm能默认反序列化的元素进行反序列化操作 this.stuage = s.readInt();// 自己完成stuage的反序列化操作 } }
本节目的:了解一下对一些序列化的优化问题
4) transient关键字
加了之后不会对transient修饰的属性进行JVM默认的序列化,但是可以自己对该属性另外写方法进行序列化(并不是所有的元素都要进行序列化,可节省空间)
方法签名:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
从ArrayList源码拷贝过来的方法签名,用来对transient关键字修饰的属性进行序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
从ArrayList源码拷贝过来的方法签名,用来对transient关键字修饰的属性进行反序列化
代码:
类:Student
用transient修饰的属性:private transient int age;
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm默认能序列化的元素进行序列化
s.writeInt(age);//把用transient修饰的属性进行序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{
s.defaultReadObject();//把jvm默认能反序列化的元素进行反序列化
this.age=s.readInt();//把用transient修饰的属性进行反序列化读取
}
分析ArrayList源码中序列化和反序列化的问题:
ArrayList源码的底层是对数组的一些方法的包装,这里面的数组也用transient关键字修饰,为的是不让数组中的无效元素进行序列化,从而节省空间,增加效率
defaultWriteObject()方法是虚拟机默认序列化方法
被transient修饰的属性不会被虚拟机进行默认的序列化操作。
但是可以自己完成这个成员的序列化
4
3
2
1
arraylist是自己完成序列化的不是用jvm自定义的方式<br>
因为arraylist有扩容机制 所以里面封装的那个数组可能没有放满<br>
所以为了减少开销 只序列化有信息的部分
对于对象中某个属性加上transient关键字可以是起步默认呗自动化,但仍可手动自动化。方法是重写类中的readObject方法与writeObject方法如下:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm能序列化的元素自动序列化
s.writeInt(stuAge);//手动将transient元素序列
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
this.stuAge = s.readInt();
}
transient这种做法的作用在于比如说有一个属性是一个数组,但这个数组并没有被占满,未被占满的元素空间就不应该被序列化应该逐个逐个手动序列化,直到将所有被占据的数组空间序列化就结束
transient关键字
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
4)但可以通过writeObject和readObject自己完成序列化和反序列化arraylist是自己完成序列化的不是用jvm自定义的方式<br>
因为arraylist有扩容机制 所以里面封装的那个数组可能没有放满<br>
所以为了减少开销 只序列化有信息的部分
对于对象中某个属性加上transient关键字可以是起步默认呗自动化,但仍可手动自动化。方法是重写类中的readObject方法与writeObject方法如下:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm能序列化的元素自动序列化
s.writeInt(stuAge);//手动将transient元素序列
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
this.stuAge = s.readInt();
}
transient这种做法的作用在于比如说有一个属性是一个数组,但这个数组并没有被占满,未被占满的元素空间就不应该被序列化应该逐个逐个手动序列化,直到将所有被占据的数组空间序列化就结束
transient关键字
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
4)但可以通过writeObject和readObject自己完成序列化和反序列化