Serializable(静态变量序列化?)与Externalizable(ClassCastException)

本文探讨了Java中的序列化接口Serializable和Externalizable的区别。Serializable接口默认序列化对象的所有属性,除了静态变量和被transient修饰的字段。而实现Externalizable接口允许自定义序列化和反序列化过程,但可能导致类型错误或需要额外处理静态变量。建议根据需要序列化的属性数量选择适合的接口。同时,实现Externalizable的read方法时要注意属性顺序,不正确的顺序可能导致问题。

被序列对象(bean)实现Serializable或Externalizable接口,

实现Serializable接口的对象可以序列化静态变量和被transient修饰的属性。

PS:如果发现静态变量可以被序列化的假象,其实是JVM中的值,可以在序列化与反序列代码中重设静态变量值证明。

Externalizable接口为Serializable的子接口,其中有两个方法

writeExternal(ObjectOutput out)
 readExternal(ObjectInput in) 

在练习中发现

public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(this);
}

无法读取其完整属性,或出现类型错误。所以说如果想一次序列化所有属性,而不是在实现一行行把所有属性都读写,还是用Serializable接口。简而言之,就是根据你想序列化和不想序列化属性的多少来决定用Serializable还是Externalizable接口。

言归正传,Externalizable接口中的方法可以实现静态变量和被transient(Externalizable中也能用,然并卵)修饰的属性的序列化。

PS:当你实现读属性时可以不注意代码的顺序

public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(stuAge);
    out.writeObject(stuLength);
    out.writeObject(stuName);
    out.writeObject(MAYBE);
    
}
但是实现写方法时,就要注意代码顺序,不然会出现类型转换错误(ClassCastException)哦。

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    this.stuAge = (Integer) in.readObject();
    this.stuLength = (Float) in.readObject();
    this.stuName = (String) in.readObject();
    this.MAYBE = (String ) in.readObject();

}

毕竟一直在对一个对象进行操作。至于重排序可能会出现的状况,谁知道呢,等学\遇到再说吧。

当然你也可以在实现读的时候就指定类型比如readInt(),readFloat()等,然而可能会出现OptionalDataException,

至于原因请转看http://jianghuguke.iteye.com/blog/939786

最后上代码:

main

import java.io.*;

/**
 * Created by T1 on 2018/3/17.
 */
public class Main{
    public static void main(String[] args) throws IOException {
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\T1\\Desktop\\112\\1.txt"));
        StuBean stu = new StuBean("t1",18,20);
        outputStream.writeObject(stu);
        outputStream.flush();
        outputStream.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\T1\\Desktop\\112\\1.txt"));
        stu.setMAYBE("321");//测试静态变量
        Object obj = null;
        try {
            obj = ois.readObject();
            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(obj);

    }
}

bean

package gysh;

import java.io.*;

public class StuBean implements Externalizable{
    private String stuName;
    private int stuAge;
    private  transient float stuLength;
    private static  String MAYBE = "s1";

    public static void setMAYBE(String MAYBE) {
        StuBean.MAYBE = MAYBE;
    }

    public StuBean() {
    }

    public StuBean(String stuName, int stuAge, float stuLength) {
        this.stuName = stuName;
        this.stuAge = stuAge;
        this.stuLength = stuLength;
    }

    public float getStuLength() {
        return stuLength;
    }

    public void setStuLength(float stuLength) {
        this.stuLength = stuLength;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public int getStuAge() {
        return stuAge;
    }

    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }


    @Override
    public String toString() {
        return MAYBE + "name is: "+getStuName()+" and age is:"+getStuAge()+" but length is:"+getStuLength();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(stuAge);
        out.writeObject(stuLength);
        out.writeObject(stuName);
        out.writeObject(MAYBE);

    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.stuAge = (Integer) in.readObject();//注意大小顺序,不然ClassCastException
        this.stuLength = (Float) in.readObject();
        this.stuName = (String) in.readObject();
        this.MAYBE = (String ) in.readObject();

    }
}
Last but not least   作者能力有限,如有遗漏或错误还望指出,谢谢!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值