[Java]serialVersionUID是干什么用的?(一)

听大侠们说,偶尔看看Java源码,可以提升编程功力,赶紧屁颠屁颠下载了一份。先研究哪个类好呢?平常用最多的类就是字符串操作了,先看String类吧。上来就被这行代码吸引住了:

private static final long serialVersionUID = -6849794470754667710L;

其实这是句很普通的语句,就是定义一个序列号。Java源码里有大量的类都有这么一个序列号,但是这个序列号具体干什么用的,这么多年还真没仔细研究过(这么多年都是混过来的吗?汗)。

照例还是百度一下吧,以下是说了等于没说的解释:

• 把Java对象转换为字节序列的过程称为对象的序列化。 
• 把字节序列恢复为Java对象的过程称为对象的反序列化。

以下是通俗易懂的解释:

举个例子,你编写了一款游戏,保存记录时把所有状态一一保存非常麻烦,这时就可以使用Serializable(序列化接口),它的作用是可以将一个对象实例序列化,序列化后你可以选择将它保存在你需要的位置。

相对的,读取后生成的对象所有属性(除了设置为瞬时值的属性)将和原对象的属性相同(只是内存地址不同)。

这样可以方便的将一个java对象写入到磁盘中,保存该对象的所有状态!

我觉得吧,把Serializable翻译成“序列化”的人应该打屁屁,字面上完全无法理解这一概念,还不如直接翻译成“对象存档”。当然现在“序列化”这个词已经成专业术语了,大家都这么用,我们也跟着用就是了。

概念现在我们是理解了,具体怎么用呢?

假设我们开发一款“坦克大战”的游戏,我们要将游戏中随机生成的坦克的位置存档起来,然后读档的时候再把该坦克在相应的位置显示出来。
■坦克类 (注意这个类必须实现Serializable 接口,这是关键)

import java.io.Serializable;
import java.util.Random;

public class Tank implements Serializable {
    private static final long serialVersionUID = 123456789L;
    public int positionX;
    public int positionY;

    public Tank() {
        Random rand = new Random();
        this.positionX = rand.nextInt(1024);
        this.positionY = rand.nextInt(768);
    }

    public void showPosition() {
        System.out.println("PositionX:" + this.positionX + "," + "PositionY:" + this.positionY);
    }
}

■游戏存档类(序列化类):

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class GameSave {

    public static void main(String[] args) throws IOException {
        Tank tank = new Tank();
        FileOutputStream fos = new FileOutputStream("Tank.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(tank);

        System.out.print("Game saved!  ----> ");
        tank.showPosition();

        oos.flush();
        oos.close();
    }

}

■游戏读档类(反序列化类):

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class GameLoad {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        FileInputStream fis = new FileInputStream("Tank.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Tank tank = (Tank) ois.readObject();

        System.out.print("Game loaded! ----> ");
        tank.showPosition();

        ois.close();
    }

}

先执行GameSave类,执行结果如下:

Game saved! —-> PositionX:842,PositionY:620

打开生成的Tank.txt,除了对象名和属性名,全是乱码,不过不要紧,程序顺利把随机生成的Tank对象保存了下来,我们知道这一点就可以了。
这里写图片描述

好了,然后执行GameLoad类,执行结果如下:

Game loaded! —-> PositionX:842,PositionY:620

可以看出读档出来的坐标,和对象生成时的坐标是一致的。你隔几天几月几年以后,再运行GameLoad类,也还是这个坐标。

除了游戏项目,还有什么地方可以应用到序列化和反序列化呢?估计大家都想到了搜索网站和购物网站。以前的网站一般是用cookie记录用户的上网习惯,但有个弊端,用户清空cookie就什么都没有了。现在有了序列化,我们完全可以把用户习惯保存到文件或数据库中,需要时再读出来分析。

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值