与手机配对好了的蓝牙耳机怎么配对手机,每次开机都不是耳机状态,点按耳机开关键可语音拨号,如何设置才可变成耳机?

1到底这个序列化有啥作用?
面向对象的程序在运行的时候会创建一个复杂的对象图,经常要以二进制的方法序列化这个对象图,这个过程叫做Archiving. 二进制流可以通过网络或写入文件中(来源于某教材的一段话)
&本人的理解是当你于写数据需要本地存储时,即将你的数据写到硬盘上的时候,你就必须对他进行序列化,转换成二进制文件,从而便于在磁盘上的读写,同理在取出的时候必须将其在反序列化,这样才能将数据读出来,就好比加密和揭秘的过程。
2 为什么我将数据写到plist 中的时候,也是存储到本地的磁盘上,但是我就没有序列化啊?
&大家有没有发现,其实plist 的数据是类型是有限制的,就那么几种特定的数据类型,,nsstring &,大家有没有尝试过将一个自己定义的类放进去(写进plist ),在读出来?
结果是什么大家可以先猜想。
其实在nsstring 的类的定义中已经添加了协议 即他是实现了nscoding 代理的方法的。
@interface NSString : NSObject
3 NScoder &和 NScoding&
NScoding 是一个协议,主要有下面两个方法
-(id)initWithCoder:(NSCoder *)//从coder中读取数据,保存到相应的变量中,即反序列化数据
-(void)encodeWithCoder:(NSCoder *)// 读取实例变量,并把这些数据写到coder中去。序列化数据
NSCoder 是一个抽象类,抽象类不能被实例话,只能提供一些想让子类继承的方法。
NSKeyedUnarchiver &&从二进制流读取对象。
NSKeyedArchiver &&&&&&把对象写到二进制流中去。
4一个简单的例子
一般是在自己定义的类中需要在.h 文件中加入
在.m 文件众实现他的的两个代理方法,这个代理方法将会被自动调用
- (void)encodeWithCoder:(NSCoder *)aCoder&
&&&&[aCoder encodeObject:self.InsureSolutionID forKey:@"personName"];
&&&&[aCoder encodeObject:self.InsureSolutionName forKey:@"personAge"];
- (id)initWithCoder:(NSCoder *)aDecoder&
&&&&self = [super init];
&&&&if (self)&
&&&&&&&&self.InsureSolutionID = [aDecoder decodeObjectForKey:@"personName"];
&&&&&&&&self.InsureSolutionName = [aDecoder decodeObjectForKey:@"personAge"];
以上是对该类序列化和反序列化。
&NSData *archiveCarPriceData = [NSKeyedArchiver archivedDataWithRootObject:self.DataArray];
&&&&[[NSUserDefaults standardUserDefaults] setObject:archiveCarPriceData forKey:@"DataArray"];
&NSData *myEncodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"DataArray"];
&&&&&self.dataList = [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
阅读(...) 评论()package cn.btkj.
import java.util.ArrayL
import java.util.L
import com.dyuproject.protostuff.LinkedB
import com.dyuproject.protostuff.ProtostuffIOU
import com.dyuproject.protostuff.S
import com.dyuproject.protostuff.runtime.RuntimeS
项目中http通信离不开对象的序列化和反序列化,以前框架使用的是xml,通用、可读性强,
对于对速度要求不高的系统来说,的确是一种不错的选择。然而最近的一个需求需要使用protobuf,因为其速度比xml快非常多,
而业界说到java的序列化和反序列化,更离不开基于protobuf的protostuff
public class ProtostuffUtil {
public static List&byte[]& serializeProtoStuffObjectList(List list,Class clazz) {
if(list == null
list.size() &= 0) {
long start = System.currentTimeMillis() ;
List&byte[]& bytes = new ArrayList&byte[]&();
schema = RuntimeSchema.getSchema(clazz);
LinkedBuffer buffer = LinkedBuffer.allocate(4096);
byte[] protostuff =
for(Object p : list) {
protostuff = ProtostuffIOUtil.toByteArray(p, schema, buffer);
bytes.add(protostuff);
} finally {
buffer.clear();
long end = System.currentTimeMillis() ;
System.out.println(&usetime is&+(end - start));
public static List
deserializeProtoStuffDataListToObjectList(
List&byte[]& bytesList,Class clazz) {
if(bytesList == null || bytesList.size() &= 0) {
long start = System.currentTimeMillis() ;
schema = RuntimeSchema.getSchema(clazz);
List&Object& list = new ArrayList&Object&();
for(byte[] bs : bytesList) {
Object obj =
obj = clazz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ProtostuffIOUtil.mergeFrom(bs,obj, schema);
list.add(obj);
long end = System.currentTimeMillis() ;
System.out.println(&usetime is&+(end - start));
public static
serializeProtoStuffObject(Object obj,Class clazz) {
if(obj == null) {
long start = System.currentTimeMillis() ;
schema = RuntimeSchema.getSchema(clazz);
LinkedBuffer buffer = LinkedBuffer.allocate(4096);
byte[] protostuff =
protostuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
long end = System.currentTimeMillis() ;
System.out.println(&usetime is&+(end - start));
public static Object
deserializeProtoStuffDataListToProductsObject(
bytes,Class clazz) {
if(bytes == null) {
long start = System.currentTimeMillis() ;
schema = RuntimeSchema.getSchema(clazz);
Object obj =
obj = clazz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ProtostuffIOUtil.mergeFrom(bytes,obj, schema);
long end = System.currentTimeMillis() ;
System.out.println(&usetime is&+(end - start));
用到的maven依赖:
&& &&&& &dependency&
&& &&& &&&& &groupId&com.dyuproject.protostuff&/groupId&
&& &&& &&&& &artifactId&protostuff-core&/artifactId&
&& &&& &&&& &version&1.0.8&/version&
&& &&& &&/dependency&
&& &&& &&dependency&
&& &&& &&&& &groupId&com.dyuproject.protostuff&/groupId&
&& &&& &&&& &artifactId&protostuff-runtime&/artifactId&
&& &&& &&&& &version&1.0.8&/version&
&& &&& &&/dependency&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:21601次
排名:千里之外
原创:19篇
(1)(1)(2)(1)(6)(2)(5)(5)(2)Java中对象序列化与反序列化详解
作者:異次元藍客
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Java中对象序列化与反序列化,较为详细的分析了java中对象序列化的概念、原理、实现方法及相关注意事项,具有一定参考借鉴价值,需要的朋友可以参考下
本文实例讲述了Java中对象序列化与反序列化。分享给大家供大家参考。具体如下:
对象序列化(Serializable)是指将对象转换为字节序列的过程,而反序列化则是根据字节序列恢复对象的过程。
序列化一般用于以下场景:
1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。
对象所属的类必须实现Serializable或是Externalizable接口才能被序列化。对实现了Serializable接口的类,其序列化与反序列化采用默认的序列化方式,Externalizable接口是继承了Serializable接口的接口,是对Serializable的扩展,实现了Externalizable接口的类完全自己控制序列化与反序列化行为。
Java.io.ObjectOutputStream代表对象输出流,其方法writeObject(Object obj)可以实现对象的序列化,将得到的字节序列写到目标输出流中。
Java.io.ObjectInputStream代表对象输入流,其readObject()方法能从源输入流中读取字节序列,将其反序列化为对象,并将其返回。
二、序列化的几种方式
假设定义了一个Customer类,根据Customer实现序列化方式的不同,可能有以下几种序列化方式:
1.实现Serializable,未定义readObject和writeObject方法
ObjectOutputStream使用JDK默认方式对Customer对象的非transient的实例变量进行序列化;
ObjectInputStream使用JDK默认方式对Customer对象的非transient的实例变量进行反序列化。
2.实现Serializable,并定义了readObject和writeObject方法
ObjectOutputStream调用Customer类的writeObject(ObjectOutputStream out)方法对Customer对象的非transient的实例变量进行序列化;
ObjectInputStream调用Customer类的readObject(ObjectInputStream in)方法对Customer对象的非transient的实例变量进行反序列化。
3.实现Externalizable,定义readExternal和writeExternal方法
ObjectOutputStream调用Customer类的writeExternal方法对Customer对象的非transient实例变量进行序列化;
ObjectInputStream首先通过Customer类的无参数构造函数实例化一个对象,再用readExternal方法对Customer对象的非transient实例变量进行反序列化。
三、Serializable接口
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
在反序列化过程中,将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。可序列化的子类必须能够访问无参数构造方法。可序列化子类的字段将从该流中恢复。
当遍历一个类视图时,可能会遇到不支持 Serializable 接口的对象。在此情况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。
1.准确签名
在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法:
private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundE
private void readObjectNoData() throws ObjectStreamE
writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以恢复它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。
readObject 方法负责从流中读取并恢复类字段。它可以调用 in.defaultReadObject 来调用默认机制,以恢复对象的非静态和非瞬态字段。defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应指定字段保存的对象的字段。这用于处理类演化后需要添加新字段的情形。该方法本身不需要涉及属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。
在序列化流不列出给定类作为将被反序列化对象的超类的情况下,readObjectNoData 方法负责初始化特定类的对象状态。这在接收方使用的反序列化实例类的版本不同于发送方,并且接收者版本扩展的类不是发送者版本扩展的类时发生。在序列化流已经被篡改时也将发生;因此,不管源流是“敌意的”还是不完整的,readObjectNoData 方法都可以用来正确地初始化反序列化的对象。
将对象写入流时需要指定要使用的替代对象的可序列化类,应使用准确的签名来实现此特殊方法:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamE
此writeReplace方法将由序列化调用,前提是如果此方法存在,而且它可以通过被序列化对象的类中定义的一个方法访问。因此,该方法可以拥有私有 (private)、受保护的(protected) 和包私有 (package-private) 访问。子类对此方法的访问遵循 java 访问规则。
在从流中读取类的一个实例时需要指定替代的类应使用的准确签名来实现此特殊方法。
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamE
此readResolve方法遵循与writeReplace相同的调用规则和访问规则。
如果一个类定义了readResolve方法,那么在反序列化的最后将调用readResolve方法,该方法返回的对象为反序列化的最终结果。
2.serialVersionUID
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。
3.Externalizable接口
Externalizable是Serailizable的扩展,实现Externalizable接口的类其序列化有以下特点:
序列化时调用类的方法writeExternal,反序列化调用readExternal方法;
在执行反序列化时先调用类的无参数构造函数,这一点与默认的反序列化是不同的,因此对实现Externalizable接口来实现序列化的类而言,必须提供一个public的无参数构造函数,否则在反序列化时将出现异常。
如果采用默认的序列化方式,只要让一个类实现Serializable接口,其实例就可以被序列化。通常,专门为继承而设计的类应该尽量不要实现Serializable接口,因为一旦父类实现了Serializable接口,其所有子类也都是可序列化的了。
默认的序列化方式的不足之处:
1.直接对对象的不宜对外公开的敏感数据进行序列化,这是不安全的;
2.不会检查对象的成员变量是否符合正确的约束条件,有可能被篡改数据而导致运行异常;
3.需要对对象图做递归遍历,如果对象图很复杂,会消耗很多资源,设置引起Java虚拟机的堆栈溢出;
4.使类的接口被类的内部实现约束,制约类的升级与维护。
通过实现Serializable接口的private类型的writeObject()和readObject(),或是实现Externalizable接口,并实现writeExternal()与readExternal()方法,并提供public类型的无参数构造函数两种方式来控制序列化过程可以有效规避默认序列化方式的不足之处。
希望本文所述对大家的java程序设计有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具对象在java中是以堆的方式存储。有时候需要复制对象或者存储对象,而不是对象的引用,这时候就需要用的对象的序列化和反序列化。
&Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
很详细的博客。
简单的来说大概有几点注意事项:
对象要实现了Serializable 接口
如果序列化和反序列化的serialVersionUID不同则反序列化失败,因为java是通过这个来进行序列化验证的。因此最好还是要定义serialVersionUID&
序列化保存的是对象的状态,静态变量属于类的状态,因此&序列化并不保存静态变量
Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
一个子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同。反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
* Copyright &
&a href="/thinkgem/jeesite"&JeeSite&/a& All rights reserved.
4 package com.mon.
6 import java.io.ByteArrayInputS
7 import java.io.ByteArrayOutputS
8 import java.io.ObjectInputS
9 import java.io.ObjectOutputS
10 import java.lang.reflect.M
12 import mons.lang3.StringU
* 对象操作工具类, 继承mons.lang3.ObjectUtils类
* @author ThinkGem
* @version
19 public class ObjectUtils extends mons.lang3.ObjectUtils {
* 注解到对象复制,只复制能匹配上的方法。
* @param annotation
* @param object
public static void annotationToObject(Object annotation, Object object){
if (annotation != null){
Class&?& annotationClass = annotation.getClass();
Class&?& objectClass = object.getClass();
for (Method m : objectClass.getMethods()){
if (StringUtils.startsWith(m.getName(), "set")){
String s = StringUtils.uncapitalize(StringUtils.substring(m.getName(), 3));
Object obj = annotationClass.getMethod(s).invoke(annotation);
if (obj != null && !"".equals(obj.toString())){
if (object == null){
object = objectClass.newInstance();
m.invoke(object, obj);
} catch (Exception e) {
// 忽略所有设置失败方法
* 序列化对象
* @param object
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
if (object != null){
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
return null;
* 反序列化对象
* @param bytes
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
if (bytes != null && bytes.length & 0){
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
java.io.ObjectOutputStream:表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream:表示对象输入流
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
本示例中,将对象序列化为byte数组,首先创造一个ByteArrayOutputStream字节数组输出流,表示输出。然后使用ObjectOutputStream(字节数组输出流)来构造一个对象输出流,表示将对象输出到字节数组输出流中。最后通过&oos.writeObject(object);将object写入字节数组输出流,再转换为字节数组。反序列则相反。
阅读(...) 评论()

我要回帖

更多关于 捷波朗蓝牙耳机配对 的文章

 

随机推荐