静态字段如何序列化? --《JAVA编程思想》88

当对象中包含静态字段时,该如何进行序列化呢?

我们先来看一个模拟 CAD 系统的例子。

Shape 为一个抽象基类,定义了基本的构造方法、color 的 get/set 抽象方法、生成三个导出类的工厂方法,以及改写了 toString() 方法。

abstract class Shape implements Serializable {

    public static final int RED = 1, BLUE = 2, GREEN = 3;

    private int xPos, yPos, dimension;

    private static Random rand = new Random(47);

    private static int counter = 0;

    public abstract void setColor(int newColor);

    public abstract int getColor();

    public Shape(int xPos, int yPos, int dimension) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.dimension = dimension;
    }

    @Override
    public String toString() {
        return getClass() + "{" +
                "color=" + getColor() +
                ",xPos=" + xPos +
                ", yPos=" + yPos +
                ", dimension=" + dimension +
                "}\n";
    }

    public static Shape randomFactory() {
        int xVal = rand.nextInt(100);
        int yVal = rand.nextInt(100);
        int dim = rand.nextInt(100);
        switch (counter++ % 3) {
            default:
            case 0:
                return new Circle(xVal, yVal, dim);
            case 1:
                return new Square(xVal, yVal, dim);
            case 2:
                return new Line(xVal, yVal, dim);
        }
    }


}

然后,展示 Shape 的三个导出类 Circle 、Square 、Line 。

public class Circle extends Shape {

    private static int color = RED;

    public Circle(int xPos, int yPos, int dimension) {
        super(xPos, yPos, dimension);
    }

    @Override
    public void setColor(int newColor) {
        color=newColor;
    }

    @Override
    public int getColor() {
        return color;
    }

}
public class Square extends Shape {

    private static int color;

    public Square(int xPos, int yPos, int dimension) {
        super(xPos, yPos, dimension);
        color = RED;
    }

    @Override
    public void setColor(int newColor) {
        color = newColor;
    }

    @Override
    public int getColor() {
        return color;
    }

}
public class Line extends Shape {

    private static int color = RED;

    public Line(int xPos, int yPos, int dimension) {
        super(xPos, yPos, dimension);
    }

    @Override
    public void setColor(int newColor) {
        color = newColor;
    }

    @Override
    public int getColor() {
        return color;
    }

    public static void serializeStaticState(ObjectOutputStream os) throws IOException {
        os.writeInt(color);
    }

    public static void deserializeStaticState(ObjectInputStream in) throws IOException {
        color = in.readInt();
    }

}

接下来,来看 Shape 集合的序列化过程。

public class StoreCADState {

    public static void main(String[] args) throws IOException {
        List<Shape> shapes = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            shapes.add(Shape.randomFactory());
        }
        for (int i = 0; i < 10; i++) {
            shapes.get(i).setColor(Shape.GREEN);
        }
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("CADState.out"));
        Line.serializeStaticState(out);
        out.writeObject(shapes);
        System.out.println(shapes);
    }

}

生成 Shape 集合后,将集合中的 Shape 导出类的 color 都设置为 Shape.GREEN

Line.serializeStaticState(ObjectOutputStream os)将Line 中的 color 变量写入序列化文件中,随后将整个 Shape 集合进行序列化。

[class mtn.baymax.charpter18.Circle{color=3,xPos=58, yPos=55, dimension=93}
, class mtn.baymax.charpter18.Square{color=3,xPos=61, yPos=61, dimension=29}
, class mtn.baymax.charpter18.Line{color=3,xPos=68, yPos=0, dimension=22}
, class mtn.baymax.charpter18.Circle{color=3,xPos=7, yPos=88, dimension=28}
, class mtn.baymax.charpter18.Square{color=3,xPos=51, yPos=89, dimension=9}
, class mtn.baymax.charpter18.Line{color=3,xPos=78, yPos=98, dimension=61}
, class mtn.baymax.charpter18.Circle{color=3,xPos=20, yPos=58, dimension=16}
, class mtn.baymax.charpter18.Square{color=3,xPos=40, yPos=11, dimension=22}
, class mtn.baymax.charpter18.Line{color=3,xPos=4, yPos=83, dimension=6}
, class mtn.baymax.charpter18.Circle{color=3,xPos=75, yPos=10, dimension=42}
]

从打印结果可以看出所有的 Shape 导出类的 color 都被更改为 3 。

那么,再来看看反序列化的过程。

public class RecoverCADState {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("CADState.out"));
        Line.deserializeStaticState(in);
        List<Shape> shapes = (List<Shape>) in.readObject();
        System.out.println(shapes);
    }

}
[class mtn.baymax.charpter18.Circle{color=1,xPos=58, yPos=55, dimension=93}
, class mtn.baymax.charpter18.Square{color=0,xPos=61, yPos=61, dimension=29}
, class mtn.baymax.charpter18.Line{color=3,xPos=68, yPos=0, dimension=22}
, class mtn.baymax.charpter18.Circle{color=1,xPos=7, yPos=88, dimension=28}
, class mtn.baymax.charpter18.Square{color=0,xPos=51, yPos=89, dimension=9}
, class mtn.baymax.charpter18.Line{color=3,xPos=78, yPos=98, dimension=61}
, class mtn.baymax.charpter18.Circle{color=1,xPos=20, yPos=58, dimension=16}
, class mtn.baymax.charpter18.Square{color=0,xPos=40, yPos=11, dimension=22}
, class mtn.baymax.charpter18.Line{color=3,xPos=4, yPos=83, dimension=6}
, class mtn.baymax.charpter18.Circle{color=1,xPos=75, yPos=10, dimension=42}
]

我们发现 Circle 和 Square 原本存储的 color 值丢失了,变为了该字段的默认值(Circle 的 color 默认为 RED = 1 和 Square 的 color 默认没有初始化,故为 0 )。

而 Line 中的 color 则被顺利还原了,这是因为之前我们在序列化时,通过Line.serializeStaticState(ObjectOutputStream os)手动将 color 写入了序列化文件中;在反序列化时,再通过 Line.deserializeStaticState(ObjectOutputStream os) 重设 Line 中静态变量 color 的值。

综上所述可以得出,Class 类在序列化时,并不会保存当前对象的 static 值,如果我们需要保存 static 值的实时状态,则需要在序列化时手动写入,反序列化时手动读取进行恢复。


本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaymaxCS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值