java序列化与反序列化(5)------反序列化时对象的创建方式
来源:互联网 发布:淘宝评论在哪里看 编辑:程序博客网 时间:2024/06/16 22:34
我在前四篇文章都讲了和序列化相关的东西,在第四篇文章中讲了通过实现Serializable,Cloneable这两个接口来实现深拷贝,但是一直有一个问题值得再讨论一下那就是:反序列化时对象是怎么创建的?
在第四篇文章中我们看到,不管通过实现Cloneable接口还是Serializable来进行深拷贝创建新对象时,都没有调用任何的构造函数进行创建对象,这看起来好像是jvm直接操作内存创建了对象。
我们知道java中创建对象的方式有如下三种:
- 通过new关键字创建对象,这个过程一定是需要调用构造函数的
- 反射Class.forName(classFullPathName).newInstance()创建对象,一定要调用默认的无参构造函数
- 通过反射Player.class.getConstructor(int.class,String.class).newInstance()创建对象,一定要调用相应的构造函数
可以运行如下的代码进行测试:
我们思考在序列化时写入字节流中确实有类的全路径名,从中我们可以获得Class信息,并可以通过调用构造函数的方式创建对象,但是我们在序列化时并不是将所有的域都序列化了,如果类存在某个构造函数中验证了某些参数的合法性,如果不合法抛出异常的这种逻辑,那么调用构造函数创建对象就会直接抛出异常。这样想来也确实不能够通过调用构造函数创建对象。当然了我们在序列化时并没有要求被序列化的类,一定要提供无参的公共构造函数。这样一分析在不涉及父子继承关系的类进行反序列化时,是不太可能通过调用构造函数进行创建对象的。
/** * * @author yujie.wang * */public class CreateObjectTest {public static void main(String[] args) {// TODO Auto-generated method stub//createByNew();String classFullPathName = "com.yujie.createbean.Player";createByReflect1(classFullPathName);createByReflect2();createByReflect3();}/** * 通过new关键字创建对象 一定显示地调用构造函数 */public static void createByNew(){Player yujie = new Player(20,"yujie.wang");yujie.introduceMyself();}/** * 通过反射Class.forName(classFullPathName).newInstance()创建对象 * 一定要调用默认的无参构造函数 * @param classFullPathName */public static void createByReflect1(String classFullPathName){if(classFullPathName == null || classFullPathName.isEmpty()){System.out.println("classFullPathName == null || classFullPathName.isEmpty()");}Player yujie = null;try {yujie = (Player)Class.forName(classFullPathName).newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} if(yujie != null){yujie.introduceMyself();}else {System.out.println("yujie == null");}}/** * 通过反射Class.forName(classFullPathName).newInstance()创建对象 * 一定要调用默认的无参构造函数 */public static void createByReflect2(){try {Player yujie = Player.class.newInstance();yujie.introduceMyself();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 通过反射Player.class.getConstructor(int.class,String.class).newInstance()创建对象 * 一定要调用相应的构造函数 */public static void createByReflect3(){try {Constructor<Player> c = Player.class.getConstructor(int.class,String.class);Player yujie = c.newInstance(20,"yujie.wang");yujie.introduceMyself();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}
我们思考在序列化时写入字节流中确实有类的全路径名,从中我们可以获得Class信息,并可以通过调用构造函数的方式创建对象,但是我们在序列化时并不是将所有的域都序列化了,如果类存在某个构造函数中验证了某些参数的合法性,如果不合法抛出异常的这种逻辑,那么调用构造函数创建对象就会直接抛出异常。这样想来也确实不能够通过调用构造函数创建对象。当然了我们在序列化时并没有要求被序列化的类,一定要提供无参的公共构造函数。这样一分析在不涉及父子继承关系的类进行反序列化时,是不太可能通过调用构造函数进行创建对象的。
阅读全文
0 0
- java序列化与反序列化(5)------反序列化时对象的创建方式
- Java 对象的序列化与反序列化实践
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- 【Java】对象的序列化与反序列化
- java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- JAVA对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- java对象的序列化与反序列化
- Java对象的序列化与反序列化
- Java对象的序列化与反序列化
- 硬件电路设计基础:二极管半导体
- 华为存储
- centos安装配置hadoop超详细过程【转】
- 动态规划小记
- [agc017f]Zigzag
- java序列化与反序列化(5)------反序列化时对象的创建方式
- 杂志社投稿流程
- leetcode---path-sum-ii---树
- bzoj 2815: [ZJOI2012]灾难
- 【算法】【Greedy】Patching Array
- 关于顺序表与链表的区别
- centos7.0安装kvm【转】
- 台式机组RAID(SSD 256G*2 + RAID0)
- Node编码规范