本题主要不讲serialVersionUID的作用,而是讲后面的一串数字的含义。当然也会对java中的serialVersionUID的作用进行说明。这篇文章是我积压了很久的一篇文章。写了一半,几个月后才发现,就拿出来整理一下。1、serialVersionUID的作用通过java进行网络间数据传输不能直接传递对象。需要在发送端拆分数据,在接收端重新加载拆分后的数据。这种拆分和重组的方法称为序列化。下面举个例子:(1)在不指定serialVersionUID的情况下,先定义一个User类,继承Serializable接口,然后序列化publicstaticvoidmain(String[]args)throwsException{//SerializeUseran=newUser();FileOutputStreamfos=newFileOutputStream("user");ObjectOutputStreamoos=newObjectOutputStream(fos);oos.writeObject(an);oos.close();}反序列化publicstaticvoidmain(String[]args)throwsException{//反序列化FileInputStreamfis=newFileInputStream("user");ObjectInputStreamois=newObjectInputStream(fis);Useru=(User)ois.readObject();System.out.println(u.name+""+u.age);ois.close();fis.close();}现在我们下面是一个序列化的例子,如果不指定serialVersionUID,程序在编译的时候会自动为我们生成一个ID号。整个过程如下:(1)发送方没有指定serialVersionUID,编译器默认为我们生成。,并序列化保存在流中发送给接收端。(2)接收端保存serialVersionUID,在反序列化时,JVM会将传入字节流中的serialVersionUID与对应本地实体的serialVersionUID进行比较。如果相同,则认为它们是一致的,可以反序列化。也就是说,当传入的ID与本地ID不一致时,就会出错。现在验证第二种情况:当我们再次反序列化时,由于JVM会将传入的字节流中的serialVersionUID与对应的本地实体的serialVersionUID进行比较,发现不一致,所以会出现异常错误:(2)指定serialVersionUID的情况不会显示。之前添加或更改了多少个字段,因为serialVersionUID是唯一的,所以反序列化不会出错。OK,这就是java中serialVersionUID的作用。其实就是给这个类加一个身份ID,用来对比序列化前后的版本。上面这个问题其实是面试中经常被问到的问题。正好又总结了一下,不过今天的话题不是关于serialVersionUID,而是后面的一串数字为什么总是没有意义呢?二、为什么总是没有意义?重要身份?java序列化后serialVersionUID,我们一般有1L或者xxxL。这些数字有什么意义?为什么我们总是需要这些无意义的ID。带着这些疑问,我们将一步步揭晓答案。1.有意义的ID有些ID是有意义的,最常见的就是我们的身份证号,一共有18位。代表省、市、县等,一般情况下,这个ID在全国是唯一的。他就像一个标识符,唯一地代表我们。标识符是可以唯一标识一个对象或对象的名称。被识别的对象可能是一些想法、物理上可数的对象或物理上不可数的物质。它的前缀ID常用于表示身份、认证过程或标识符。因此,唯一性是ID的最大特点。就像我们的身份证号码,你在全中国找不到另一个和你号码相同的人。现在我们知道了,有意义的ID通常是唯一代表对象的标识符。现在让我们把注意力转移到无意义的ID上。2.无意义的ID这个在我们的java序列化id,数据库中的自增主键,消息队列,甚至我们的TCP通信中都会用到。无意义的真正含义其实是和我们要做的事情无关,也就是说这个ID号不应该和我们的业务逻辑相关。大多数业务的主键都会使用整数,其上限一般为2^64。如果用这些数字来表示记录的ID,这辈子基本不可能用完,但是一旦我们给ID加上业务信息,就会让原本没有意义的ID变得有意义,影响其唯一性。在java序列化的例子中,你看到serialVersionUID==xxxL,你应该不会想到这串数字和这个类之间的联系。而且一旦有连接,就可能出现错误。那么为什么无意义的ID有用呢?举个例子:分布式系统中有一个分布式ID生成器,Snowflake算法会给64位整数不同的信息:Rangelengthworks0-01Notused1-4141毫秒时间戳42-465datacenteridentifier47-515machineidentifier52-6312serialnumber假设一台机器在一个时间单位内最多只能产生4096个ID,一旦超过这个数,可能会造成ID冲突或混乱,从而丢失它的独特性;该算法中涉及的时间戳、数据中心标识、机器标识无法解决唯一性问题,即使这三者完全在这个时候,仍然需要使用一个没有其他意义的序号来保证ID的唯一性.所以使用无意义ID的主要目的是利用它的唯一性保证对象的标识符不会冲突。无意义ID唯一的作用就是保证唯一性,可以帮助我们避免业务领域潜在的冲突。也提醒我们,要使用联合字段构成主键时,一定要慎重考虑。3.总结其实上面说了这么多,是想让大家有个稍微全面的认识。就像很多次一样,BB一句话说完需要很长时间。一句话总结:对于一个有意义的ID来说,身份证号是跟特定场景下的业务逻辑相关的,比如身份证号是跟每个人的唯一标识相关的。对于无意义的ID:这个ID号一旦和业务逻辑关联起来,就有重复的可能,极不安全。这时候一个无意义的ID就具有了唯一性。不管有没有意义,都是为了唯一标识,只是使用的场景不同而已。本文转载自微信公众号“愚公要移山”,可关注下方二维码。转载本文请联系愚公移山公众号。
