• 对象序列化Serializable


    一、Java对象的存储

    首先我们先来理解一下Java对象在内存中的存储!

    JVM的内存分为三个部分:栈(stack)、堆栈(heap)、方法区(method area):

    栈:主要存储基本数据类型变量、方法的形参、引用数据类型等;

    堆栈:存储实例对象;

    方法区:存储静态变量(静态常量池)、class信息等

    如:当new出来一个对象后,对象的引用在栈中分配,指向堆中的实例对象;当局部对象变量使用完后,引用立即从栈中回收,堆中的对象等待GC回收;

    再如:数组,在栈中分配数据名,堆中保存数据的大小和实例元素。

    因此,java程序中的对象实例默认都是直接存储在内存中,一旦内存中被回收或意外丢失,将无法重构;

    这就涉及到了java对象的序列化!

    二:什么是对象序列化

    在JavaBean的文章中曾提到,serializable的目的是类属性的持久化存储。比如需要开发MySQL的存储,那么将一条记录写入MySQL中的时候就需要实现Serializable接口。

    那么到底什么是对象序列化呢?

    对象序列化就是将对象实例的状态(是属性,不包括方法)保存到文件或者其它数据库,并且可以通过反序列化的方式对对象进行重构。

    (对象序列化将内存中的变量实例(如JavaBean中的User bean)转换为二进制流,更加高效地在网络或存储介质上进行传输)

    三:序列化示例

    假设有如下类LoginUser,定义有username和password两个属性,main函数中创建了一个LoginUser对象,username值为50,password值为30;

    然后将当前LoginUser对象的属性值保存到文件foo.ser中。

     1 import java.io.*;
     2 
     3 public class LoginUser {
     4     private String username;
     5     private String passwd;
     6     public String getUsername() {
     7         return username;
     8      }
     9     public void setUsername(String username) {
    10         this.username = username;
    11     }
    12     public String getPasswd() {
    13          return passwd;
    14     }
    15     public void setPasswd(String passwd) {
    16         this.passwd = passwd;
    17     }
    18  
    19 
    20     public static void main(String[] args){   
    21         LoginUser loginUser = new LoginUser();   
    22         loginUser.setUsername("50");   
    23         loginUser.setPasswd("30");   
    24    
    25         try{   
    26             FileOutputStream fs = new FileOutputStream("foo.ser");   
    27             ObjectOutputStream os =  new ObjectOutputStream(fs);   
    28             os.writeObject(loginUser);   
    29             os.close();   
    30         }catch(Exception ex){   
    31             ex.printStackTrace();   
    32         }   
    33     }  
    34 
    35 }                    

    此时,运行该代码会出现如下异常:

    1 java.io.NotSerializableException: com.longshine.zwp.test.LoginUser
    2   at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
    3   at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
    4   at com.longshine.zwp.test.LoginUser.main(LoginUser.java:29)

    提示找不到对应的序列化类型,需要对LoginUser类定义做出如下修改:

    1 public class LoginUser implements Serializable{
    2 
    3 }

    四、序列化注意事项

    a)序列化时,只对对象的状态进行保存,而不管对象的方法;
    b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

    d)静态变量不能做序列化;

    e)并不是所有的对象都能做序列化,比如Thread、socket等不能被序列化。

  • 相关阅读:
    CAP
    plugins for ST3 to frontend
    OAuth 2.0 详解
    Git SSH生成
    Android FrameWork 学习之Android 系统源码调试
    node.js安装步骤
    数据结构-- 队列 循环与顺序
    jsp之认识 servlet (基础、工作原理、容器请求处理)
    android 蓝牙开发---与蓝牙模块进行通讯 基于eclipse项目
    Android 仿微信调用第三方应用导航(百度,高德、腾讯)
  • 原文地址:https://www.cnblogs.com/yy20141204bb/p/10570366.html
Copyright © 2020-2023  润新知