java pasd_Java对象序列化(pass)

转载自:http://www.cnblogs.com/xrq730/p/4821958.html

IO操作或网络通信无法直接处理Java对象,必须将对象以某种方式表示出来,才能被IO或网络通信识别。

序列化:将一个对象转成二进制表示的字节数组,通过保存或转移这些字节数组来持久化。

反序列化:将二进制数组转化为对象。

Java序列化之需要实现java.io.Serializable接口就可以了。

默认序列化

序列化的时候又一个serialVersionUID参数,Java序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化的时候,Java虚拟机毁把传过来的字节流中的serialVersionUID和本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的实体类,可以进行反序列化,否则Java虚拟机毁拒绝对这个实例类进行反序列化病抛出异常。

生成serialVersionUID有两种方式:

1,默认的1L

2,根据类名/接口名/成员方法以及属性等来生成一个64位的Hash字段

如果实现了Serializable接口的实体类没有显式定义一个名为serialVersonUID,类型为long的变量时,Java序列化机制会根据编译的.class文件自动生成一个serialVersionUID, 如果.class没有变化,那么就算编译两次,serialVersionUID也不会变化。Java为用户定义了默认的序列化/反序列化方法,其实就是ObjectInputStream的defaultWriteObject() 和 defaultReadObject方法。

示例1 :

packagecom.basic;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;importjava.io.OutputStream;importjava.io.Serializable;public class SerializableTest implementsSerializable{

private static final long serialVersionUID = -4573981250507373015L;privateString str0;private transientString str1;private static String str2 = "aaa";publicSerializableTest(String str0, String str1) {this.str0 =str0;this.str1 =str1;

}publicString getStr0() {return this.str0;

}publicString getStr1() {return this.str1;

}public static void main(String[] args) throwsException {//TODO Auto-generated method stub

File file= new File("C:" + File.separator + "tool" + File.separator + "SerialTest.txt");

OutputStream os= newFileOutputStream(file);

ObjectOutputStream oos= newObjectOutputStream(os);

oos.writeObject(new SerializableTest("str0", "str1"));

oos.close();

InputStream is= newFileInputStream(file);

ObjectInputStream ois= newObjectInputStream(is);

SerializableTest so=(SerializableTest)ois.readObject();

System.out.println("str0 = " +so.getStr0());

System.out.println("str1 = " +so.getStr1());

}

}

结果:

str0 =str0

str1= null

序列化文件:

aced 0005 7372 001a 636f 6d2e 6261 7369632e5365 7269 616c 697a 6162 6c65 5465

7374 c085 f449 6236 0629 0200 014c 0004

7374 7230 7400 124c 6a61 76612f6c 616e

672f5374 7269 6e67 3b78 7074 0004 7374

7230

序列化文件分五部分:

第一部分:序列化文件头

第二部分:要序列化的类的描述

第三部分:对象中各种属性的描述

第四部分:该对象父类的信息,如果没有父类就没有这部分

第五部分:输出对象的属性项的实际值,如果属性项是一个对象,还会序列化这个对象

总结:

1,序列化之后保存的是类的信息,因为一个serialVersionUID对应一个类

2,被声明为transient的属性不会被序列化

3,被声明为static的属性不会被序列化,因为序列化保存的是对象的状态,而静态属性属于类不属于对象,所以不会序列化它。

自定义序列化过程

Java并不强求用户非要使用默认的序列化方式,用户也可以按照自己的喜好自己指定自己想要的序列化方式----只要你自己能保证序列化前后能得到想要的数据就好了。手动指定序列化方式的规则是:

进行序列化、反序列化时,虚拟机会首先试图调用对象里的writeObject和readObject方法,进行用户自定义的序列化和反序列化。如果没有这样的方法,那么默认调用的是ObjectOutputStream的defaultWriteObject以及ObjectInputStream的defaultReadObject方法。换言之,利用自定义的writeObject方法和readObject方法,用户可以自己控制序列化和反序列化的过程。

这是非常有用的。比如:

1、有些场景下,某些字段我们并不想要使用Java提供给我们的序列化方式,而是想要以自定义的方式去序列化它,比如ArrayList的elementData、HashMap的table(至于为什么在之后写这两个类的时候会解释原因),就可以通过将这些字段声明为transient,然后在writeObject和readObject中去使用自己想要的方式去序列化它们

2、因为序列化并不安全,因此有些场景下我们需要对一些敏感字段进行加密再序列化,然后再反序列化的时候按照同样的方式进行解密,就在一定程度上保证了安全性了。要这么做,就必须自己写writeObject和readObject,writeObject方法在序列化前对字段加密,readObject方法在序列化之后对字段解密

示例2:

packagecom.basic;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;importjava.io.OutputStream;importjava.io.Serializable;public class SerializableTest implementsSerializable{private static final long serialVersionUID = -4573981250507373015L;privateString str0;private transientString str1;private static String str2 = "aaa";publicSerializableTest(String str0, String str1) {this.str0 =str0;this.str1 =str1;

}publicString getStr0() {return this.str0;

}publicString getStr1() {return this.str1;

}private void writeObject(ObjectOutputStream s) throwsIOException {

System.out.println("serializing by myself");

s.defaultWriteObject();

s.writeInt(str1.length());for (int i=0; i

s.writeChar(str1.charAt(i));

}

}private void readObject(ObjectInputStream s) throwsClassNotFoundException, IOException {

System.out.println("deserializing by myself");

s.defaultReadObject();int length =s.readInt();char[] cs = new char[length];for (int i =0; i

cs[i]=s.readChar();

}

str1= new String(cs, 0, length);

}public static void main(String[] args) throwsException {//TODO Auto-generated method stub

File file= new File("C:" + File.separator + "tool" + File.separator + "SerialTest.txt");

OutputStream os= newFileOutputStream(file);

ObjectOutputStream oos= newObjectOutputStream(os);

oos.writeObject(new SerializableTest("str0", "str1"));

oos.close();

InputStream is= newFileInputStream(file);

ObjectInputStream ois= newObjectInputStream(is);

SerializableTest so=(SerializableTest)ois.readObject();

System.out.println("str0 = " +so.getStr0());

System.out.println("str1 = " +so.getStr1());

}

}

先通过defaultWriteObject和defaultReadObject方法序列化、反序列化对象,然后在文件结尾追加需要额外序列化的内容/从文件的结尾读取额外需要读取的内容。

复杂序列化情况总结

虽然Java的序列化能够保证对象状态的持久保存,但是遇到一些对象结构复杂的情况还是比较难处理的,最后对一些复杂的对象情况作一个总结:

1、当父类继承Serializable接口时,所有子类都可以被序列化

2、子类实现了Serializable接口,父类没有,父类中的属性不能序列化(不报错,数据丢失),但是在子类中属性仍能正确序列化

3、如果序列化的属性是对象,则这个对象也必须实现Serializable接口,否则会报错

4、反序列化时,如果对象的属性有修改或删减,则修改的部分属性会丢失,但不会报错

5、反序列化时,如果serialVersionUID被修改,则反序列化时会失败

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。
### 回答1: pasd9.5免安装版是一款非常实用的软件,它不需要进行繁琐的安装过程,可以直接运行在计算机上。 pasd9.5是一款密码管理软件,它具有强大的功能和界面友好的特点。它可以帮助用户管理和保护个人账号的密码。在现代社会中,我们必须记住众多的账号和密码,如电子邮箱、社交媒体和网上银行等。而pasd9.5可以帮助用户以一种安全和便捷的方式存储和管理这些密码。 这个免安装版的pasd9.5无需复杂的安装过程,只需解压文件即可直接运行。这对忙碌的用户来说非常方便,无需花费大量时间和精力去安装软件。 pasd9.5免安装版在功能上跟常规版本没有太大差别,用户可以通过它来创建不同的账号和密码文件夹,并将相关的账号和密码信息进行分类整理。用户可以为每个文件夹设置不同的密码,以保护自己的隐私和安全。此外,它还支持在浏览器中自动填充账号和密码,让用户能够更加便捷地登录网站。 总之,pasd9.5免安装版是一款强大且方便的密码管理软件,它的主要特点是免去了繁琐的安装步骤,可以直接运行在计算机上。它能够帮助用户安全地管理各种账号和密码,提高生活和工作的效率。 ### 回答2: Pasd9.5免安装版是一种便捷的软件版本,用户可以直接运行而无需进行繁琐的安装过程。Pasd9.5是一款功能强大的软件,被广泛应用于各种领域。 Pasd9.5免安装版具有以下几个优点。首先,它方便快捷,用户可以直接从光盘、U盘或网络中运行软件,无需将其安装到电脑的硬盘上。这对于需要在多台电脑上使用软件的用户来说非常方便,无需每次都进行安装过程。 其次,Pasd9.5免安装版也具有较低的系统资源消耗。相比于安装版,免安装版通常只需要较少的内存和硬盘空间。这对于一些配置较低的电脑来说尤为重要,可以减少资源占用对电脑性能的影响。 此外,Pasd9.5免安装版还可以保护用户的隐私安全。使用免安装版软件,用户的数据保存在光盘或外部设备上,不会留下痕迹或敏感信息在电脑上。这对于一些对隐私保护要求比较高的用户来说是一个重要的考虑因素。 总的来说,Pasd9.5免安装版是一种方便、节省资源且安全的软件选择。无论是用于个人使用还是商业用途,这种免安装版都可以提供高效的功能和便捷的使用体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值