序列化与反序列化总结(Serializable和Parcelable)
序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。
在Java中创建的对象,只要没有被回收就可以被复用,但是,创建的这些对象都是存在于JVM的堆内存中,JVM处于运行状态时候,这些对象可以复用,
但是一旦JVM停止,这些对象的状态也就丢失了。
在实际生活中,需要将对象持久化,需要的时候再重新读取出来,通过对象序列化,可以将对象的状态保存为字节数组,需要的时候再将字节数组反序列化为对象。
对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间转换,广泛用于RMI(远程方法调用)以及网络传输中。
特别注意:
a.静态成员变量属于类不属于对象,所以不会参与序列化(对象序列化保存的是对象的“状态”,也就是它的成员变量,因此序列化不会关注静态变量)
b.用transient关键字标记的成员变量不参与序列化(在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null)
(1).Serializable
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
import java.io.Serializable; public class StudentSerializable implements Serializable { //指定serialVersionUID,
//因为原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同时才能被正常的反序列化
//最好自己指定UID或者系统生成,因为如果增加或者删除了某些成员变量,那么系统就会重新生成hash值然后赋给UID,导致反序列化时候crash
private static final long serialVersionUID = 10000000000000000L; private int Uid;
private String Name ; public int getUid() {
return Uid;
}
public void setUid(int uid) {
Uid = uid;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
@Override
public String toString() {
return "StudentSerializable [Uid=" + Uid + ", Name=" + Name + "]";
} }
private void DealSerializable() throws IOException {
// Initializes The Object
StudentSerializable stu = new StudentSerializable();
stu.setUid(9027);
stu.setName("fish"); File extDir = Environment.getExternalStorageDirectory();
String filename = "tempFile.txt";
File fullFilename = new File(extDir, filename); try {
fullFilename.createNewFile();
fullFilename.setWritable(Boolean.TRUE);
fullFilename.setReadable(Boolean.TRUE); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Write Obj to File
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(fullFilename.getAbsoluteFile()));
oos.writeObject(stu);
} catch (IOException e) {
e.printStackTrace();
} finally {
//oos.close();
} // Read Obj from File
//File file = new File("tempFile.txt");
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(fullFilename.getAbsoluteFile()));
StudentSerializable newStu = (StudentSerializable) ois.readObject();
System.out.println(newStu);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
//ois.close();
}
}
在使用时,通常是和ObjectOutputStream
以及 ObjectInputStream
配套一起使用,准确的说是和ObjectOutputStream
里的writeObject ()
和 ObjectInputStream
里的 readObject ()
一起使用。writeObject()
方法是最重要的方法,用于对象序列化。如果对象包含其他对象的引用,则writeObject()方法递归序列化这些对象。
(2).Parcelable
import android.os.Parcel;
import android.os.Parcelable; public class StudentParcelable implements Parcelable{ private int Uid;
private String Name ; private Book book ; public StudentParcelable(int uid, String name) {
super();
Uid = uid;
Name = name;
} public int getUid() {
return Uid;
}
public void setUid(int uid) {
Uid = uid;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
} //功能:返回当前对象的内容描述,如果含有文件描述符,返回1
//即CONTENTS_FILE_DESCRIPTOR
//几乎所有情况都会返回0
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
} /**
* 序列化功能由writeToParcel完成,最终通过Parcel的一系列Write方法完成
*/
//功能:将当前对象写入序列化结构中,其中flags标识有两种值,0或1
//为1时标识当前对象需要作为返回值返回,不能立刻释放资源,即PARCELABLE_WRITE_RETURN_VALUE
//不过几乎所有情况都为0
@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeInt(Uid);
dest.writeString(Name);
dest.writeParcelable(book, 0);
} /**
* 反序列化由CREATOR来完成,其内部标明了如何创建序列化对象和数组
* 并通过Parcel的一系列read方法来完成反序列化
*/
public StudentParcelable(Parcel source){
Uid = source.readInt();
Name = source.readString(); //注意:book是一个可序列化对象,所以它的反序列化过程需要传递当前线程的上下文类加载器
//否则会报找不到类的错误
book = source.readParcelable(Thread.currentThread().getContextClassLoader());
} public static final Parcelable.Creator<StudentParcelable> CREATOR = new Parcelable.Creator<StudentParcelable>() { //功能: 从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层。
@Override
public StudentParcelable createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new StudentParcelable(source);
} //功能:创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。方法是供外部类反序列化本类数组使用。
@Override
public StudentParcelable[] newArray(int size) {
// TODO Auto-generated method stub
return new StudentParcelable[size];
}
}; }
Intent intent = new Intent(this,Second.class);
StudentParcelable stu = new StudentParcelable(001,"fish");
intent.putExtra("student", stu);
startActivity(intent);
Intent intent = getIntent();
StudentParcelable stu = (StudentParcelable) intent.getParcelableExtra("student");
Log.i("LOG", "student name :" + stu.getName());
Log.i("LOG", "student age :" + stu.getUid());
两者区别:
1.Serializable实现简单,而Parcelable需要实现特殊的接口
2.Serializable将对象转化为字节流存储在外部设备,需要时重新生成对象(依靠反射),因为使用反射,所以会产生大量的临时变量,从而引起频繁的GC,相比之下Parcelable性能更高,Parcelable的效率是Serializable的十倍以上,所以在内存中传输时更推荐Parcelable(比如在网络中传输对象或者进程间传输对象,还有Intent)
3.Parcelable的整个过程都在内存中进行,反序列化读取的就是原对象,不会创建新对象。要注意的是:不能使用要将数据存储在磁盘上(比如永久性保存对象,或者保存对象的字节序列到本地文件中),因为Parcel是为了更好的实现在IPC间传递对象,并不是一个通用的序列化机制,当改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取(Parcelable 是以2进制的方式写入,严重依赖写入顺序),还有就是Parcelable为了效率完全没有考虑版本间的兼容性,所以数据持久化还是要使用Serializable(比如外部设备保存对象状态或者网络传输对象)
快速解析和序列化Json对象的类库:LoganSquare
注意:
1.如果一个类想被序列化,需要实现Serializable接口。否则将抛出NotSerializableException
异常,这是因为,在序列化操作过程中会对类型进行检查,要求被序列化的类必须属于Enum、Array和Serializable类型其中的任何一种,这也是为什么Serializable虽然是一个空接口,但是只要实现了该接口就能序列化和反序列化。
2.在类中增加writeObject 和 readObject 方法可以实现自定义序列化策略,虽然这俩方法不是被显示调用,但是因为在使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法时,会通过反射的方式调用到它们。
参考:http://www.hollischuang.com/archives/1140#What%20Serializable%20Did
序列化与反序列化总结(Serializable和Parcelable)的更多相关文章
- 序列化、反序列化(Serializable特性)
//需要被实例化的类 using System.Collections; using UnityEngine; [Serializable] public class SerializableClas ...
- Android序列化之Serializable和Parcelable
PS:还有几天就开学了.先来一发. 学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Par ...
- 序列化Serializable和Parcelable
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 简单记录下序列化Serializable和Parcelable的使用方法. Android中Intent如果要传递类对象,可以通过两 ...
- Android中Serializable和Parcelable序列化对象详解
学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.P ...
- 【Android - IPC】之Serializable和Parcelable序列化
1.序列化的目的 (1)永久的保存对象数据(将对象数据保存到文件或磁盘中): (2)通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的,因此序列化的目的是将对象数据 ...
- Java序列化与反序列化(Serializable)
Java序列化与反序列化(Serializable) 特别注意: 1.要序列化的类必须实现Serializable借口 2.在反序列化(读取对象)的时候必须额外捕获EOFException 3.序列化 ...
- 使用Serializable接口进行JAVA的序列化和反序列化
OBJECT STREAMS – SERIALIZATION AND DESERIALIZATION IN JAVA EXAMPLE USING SERIALIZABLE INTERFACE Hite ...
- Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解释
遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题a,什么叫序列化和反序列化b,作用.为啥要实现这个 Serializable 接口,也就是为啥要序列化c,seria ...
- Serializable 接口与 Java 序列化与反序列化
0. 序列化的意义 从内存到本地即为本地化或者在网络中进行传输,或叫序列化,持久化. 某 Java 类实现 Serializable 接口的目的是为了可持久化(简单理解为本地化),比如网络传输或本地存 ...
随机推荐
- ArcGIS多面体(multipatch)解析(一)
从几何学的角度来说,再复杂的三维形状都可以通过足够多,足够小的三角形组合起来表达.比如矩形可以表达成两个三角形,如下图: 圆柱形可以由多个三角形排列而成: 但ArcGIS中的多面体构成并没有采用这种“ ...
- mac osx 10.9安装配置macvim
如果你已经安装了macvim,升级后又不能用了,建议你可以看看http://kodira.de/2013/10/macvim-osx-10-9-mavericks/这篇文章,如果你还没有安装,下面由我 ...
- EasyUI tree扩展获取实心节点
<script type="text/javascript"> //扩展 获得tree 的实心节点 $(function(){ $.extend($.fn.tree.m ...
- Mac下chrome的webapp hostadmin 快速切换host
首先是安装 app ,https://chrome.google.com/webstore/detail/hostadmin-app/mfoaclfeiefiehgaojbmncmefhdnikeg ...
- Nunit NMock Ncover单元测试
Nunit中如何进行事务性单元测试 单元测试要求:单元测试方法并不真正去变更数据库,也就是说单元测试不依赖于数据库中的数据.那我们如何解决执行单元测试方法后,不变更数据库中数据呢? 一般的解决方案 ...
- 基于BrokerPattern服务器框架
基于BrokerPattern服务器框架 RedRabbit 经典网游服务器架构 该图省略了专门用途的dbserver.guildserver等用于专门功能的server,该架构的优点有: l Log ...
- Arduino 各种模块篇 RGB LED灯
示例代码: 类似与这样的led,共阴rgb led,通过调节不同的亮度,组合成不同的颜色. 示例代码: /* 作者:极客工坊 时间:2012年12月18日 IDE版本号:1.0.1 发布地址:www. ...
- 2440开发板linux系统移植3G拨号上网收发短信(三)
一.用text查看模式 下面的“发”是指我敲的命令,“收”是指回车后显示的信息包括其他接收的信息. ~ >: microcom -s 115200 /dev/ttyUSB1 发:at 收:OK ...
- DLoopDetector回环检测算法
词袋模型是一种文本表征方法,它应用到计算机视觉领域就称之为BoF(bag of features),通过BoF可以把一张图片表示成一个向量.DBoW2是一个视觉词袋库,它提供了生成和使用词典的接口,但 ...
- NET仿微信Oauth2.0
这个文章先说一说Oauth2.0的原理,再到应用场景,最后才是代码实现,这样才学会最终的思想,并在应用场景使用,所谓实践出真理. 1,Oauth2.0的原理 OAuth是一个关于授权(authoriz ...