`
boy00fly
  • 浏览: 194881 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

自己动手写写:Java序列化

    博客分类:
  • JVM
 
阅读更多

从以下几个方面来讨论这个问题

 

1、序列化是用来干什么的?

     序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容就行流化。简而言之就是为了保存内存中的各种实例对象的状态,并且可以通过反序列化将实例对象的状态再读出来。

 

2、为什么需要序列化?

为了将对象转换为更加容易传输的格式,减少网络流量的开销。例如,可以序列化一个实例对象,然后使用Http通过Internet在客户端和服务端之间传输该对象,在另外一段,反序列化将从该流中重新构造对象。

 

3、什么情况下需要序列化?

  • 内存中的实例对象状态保存到存储介质时。
  • 内存中的实例对象需要在网络传输时。

4、Java中序列化的实现

Java中只需要一个类implements Serializable即可实现此类的实例对象的序列化。
通过ObjectOutputStream的writeObject方法来实现对象的序列化。通过ObjectInputStream的readObject方法类实现对象的反序列化。

请看下面的一个例子
public class Org
{
    private String orgId;
    
    private String orgName;
    
    /**
     * @return 返回 orgId
     */
    public String getOrgId()
    {
        return orgId;
    }
    
    /**
     * @param 对orgId进行赋值 */
    public void setOrgId(String orgId)
    {
        this.orgId = orgId;
    }
    
    /**
     * @return 返回 orgName
     */
    public String getOrgName()
    {
        return orgName;
    }
    
    /**
     * @param 对orgName进行赋值 */
    public void setOrgName(String orgName)
    {
        this.orgName = orgName;
    }
    
}

 

 

public class User implements Serializable
{   
    /**
     * 注释内容
     */
    private static final long serialVersionUID = -2069026676796654202L;
    
    public static String s = "ssss";

    private String userName;
    
    private String password;
    
    private Org org;
    
    /**
     * @return 返回 org
     */
    public Org getOrg()
    {
        return org;
    }

    /**
     * @param 对org进行赋值 */
    public void setOrg(Org org)
    {
        this.org = org;
    }

    /**
     * @return 返回 userName
     */
    public String getUserName()
    {
        return userName;
    }
    
    /**
     * @param 对userName进行赋值 */
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    
    /**
     * @return 返回 password
     */
    public String getPassword()
    {
        return password;
    }
    
    /**
     * @param 对password进行赋值 */
    public void setPassword(String password)
    {
        this.password = password;
    }

}
 

 

 
public class UserImpl extends User
{
    
    /**
     * 注释内容
     */
    private static final long serialVersionUID = 418270522532375203L;
    private String confimPassword;

    /**
     * @return 返回 confimPassword
     */
    public String getConfimPassword()
    {
        return confimPassword;
    }

    /**
     * @param 对confimPassword进行赋值 */
    public void setConfimPassword(String confimPassword)
    {
        this.confimPassword = confimPassword;
    }
    
}

 

  <!--------------------------------------------------------------分割线---------------------------------------------------------------!>

 

public class WriteTest
{
    
    /**
     * <一句话功能简述>
     * <功能详细描述>
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
        User user = new UserImpl();
        user.setUserName("aaa");
        user.setPassword("bbb");
        
        try
        {
            FileOutputStream fos = new FileOutputStream("User.bin");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(user);
            fos.close();
            oos.close();
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
    
}

 

   通过查看序列化后的文件:

   User.bin

 

com.serializable.UserImpl
confimPasswordt
Ljava/lang/String;xr
com.serializable.User
orgt
Lcom/serializable/Org;L
passwordq
userNameq
xppt
bbbt
aaap

 

 我们可以得出以下的结论

 1、序列化的内容包括对象的类型信息、对象的属性信息、对象的属性值信息。而对象的方法信息没有被序列化,静态变量也没有被实例化(这个其实也很好理解,序列化是序列化实例对 象的状态信息,而静态变量是属于类型的信息)。

 2、当一个对象的实例变量引用其他对象,那么序列化该对象也会把引用对象进行序列化。

 3、父类序列化那么子类也自动序列化。

 

如果我们将User类的实现序列化接口去掉,将UserImpl类的实现序列化接口加上去会怎么样呢?

我这里给出结果

 

 

com.serializable.UserImpl
confimPasswordt
Ljava/lang/String;xpp
 

 

我们有没有发现,没有序列化父类的属性以及属性值,我们得出

4、子类序列化,父类没有序列化,则子类序列化时,父类的类型信息、属性以及属性值并不会序列化。

 

 

序列化的其他一些特性比如:Transient 

Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

等等,很多信息都可以参考google,这里给出一个觉得比较容易理解的文章的链接http://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html?ca=drs-

 

 

 

 

 

 

0
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics