为了账号安全,请及时绑定邮箱和手机立即绑定

在Java中,序列化和Externalable有什么区别?

在Java中,序列化和Externalable有什么区别?

人到中年有点甜 2019-07-08 15:36:09
在Java中,序列化和Externalable有什么区别?.之间的区别是什么?Serializable和Externalizable在爪哇?
查看完整描述

3 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

序列化提供了存储和稍后重新创建对象的默认功能。它使用详细的格式定义要存储的整个对象图,例如,假设您有一个linkedList,代码如下所示,那么默认的序列化将发现所有链接的对象并进行序列化。在默认序列化中,对象完全由其存储的位构成,没有构造函数调用。

  ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("/Users/Desktop/files/temp.txt"));
        oos.writeObject(linkedListHead); //writing head of linked list
        oos.close();

但是,如果您希望有限制的序列化,或者不希望您的对象的某些部分被序列化,那么请使用Externalable。Externalable接口扩展了可序列化的接口,并添加了两个方法:writeExoun()和readExoun()。它们在序列化或反序列化时自动调用。在使用Externalable时,我们应该记住默认构造器应该是公共的,否则代码会抛出异常。请遵循以下代码:

public class MyExternalizable implements Externalizable{private String userName;private String passWord;private Integer roll;
public MyExternalizable(){}public MyExternalizable(String userName, String passWord, Integer roll){
    this.userName = userName;
    this.passWord = passWord;
    this.roll = roll;}@Overridepublic void writeExternal(ObjectOutput oo) throws IOException {
    oo.writeObject(userName);
    oo.writeObject(roll);}@Overridepublic void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException {
    userName = (String)oi.readObject();
    roll = (Integer)oi.readObject();}public String toString(){
    StringBuilder b = new StringBuilder();
    b.append("userName: ");
    b.append(userName);
    b.append("  passWord: ");
    b.append(passWord);
    b.append("  roll: ");
    b.append(roll);

    return b.toString();}public static void main(String[] args){
    try
    {
        MyExternalizable m  = new MyExternalizable("nikki", "student001", 20);
        System.out.println(m.toString());
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Desktop/files/temp1.txt"));
        oos.writeObject(m);
        oos.close();

        System.out.println("***********************************************************************");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Desktop/files/temp1.txt"));
        MyExternalizable mm = (MyExternalizable)ois.readObject();
        mm.toString();
        System.out.println(mm.toString());
    } 
    catch (ClassNotFoundException ex) 
    {
        Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch(IOException ex)
    {
        Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
    }}}

在这里,如果您注释默认构造器,那么代码将抛出在异常下面:

 java.io.InvalidClassException: javaserialization.MyExternalizable;     
 javaserialization.MyExternalizable; no valid constructor.

我们可以观察到,由于密码是敏感的信息,所以我不使用写外部(ObjectOutput Oo)方法对其进行序列化,也不会在readExoun(ObjectInput Oi)中设置它的值。这是Externalable提供的灵活性。

上述代码的输出如下:

userName: nikki  passWord: student001  roll: 20***********************************************************************userName: 
nikki  passWord: null  roll: 20

我们可以观察到,因为我们没有设置密码的值,所以它是空的。

也可以通过将密码字段声明为瞬态来实现同样的目的。

private transient String passWord;

希望能帮上忙。如果我犯了什么错,我道歉。谢谢。


查看完整回答
反对 回复 2019-07-08
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

为了完整起见,transient关键字还可以缩小两者之间的差距。

如果只想序列化对象的一部分,只需将特定字段设置为transient,将其标记为不持久化,并实现Serializable.


查看完整回答
反对 回复 2019-07-08
  • 3 回答
  • 0 关注
  • 526 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号