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

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

静态字段如何序列化? --《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 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 shapes = (List) 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 值的实时状态,则需要在序列化时手动写入,反序列化时手动读取进行恢复。


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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686381.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存