当前位置:网站首页>从源码角度分析UUID的实现原理
从源码角度分析UUID的实现原理
2022-08-10 10:58:00 【51CTO】
这是 《水煮 JDK 源码》系列 的第 11 篇文章,计划撰写100篇关于JDK源码相关的文章
UUID
的全称是 universally unique identifier
,表示通用唯一标识符,UUID
类位于 java.util
包下,自 JDK 1.5
版本新增的,它是一个 final
类,不能被继承,在平常的开发中,通常会使用 UUID
类来生成唯一的标识符,比如下面的代码:
运行后,输出的结果如下:
上面的结果中显示的就是默认的 UUID
字符串,它是由数字、字母和 - 组成,其中数字和字母共占32个字符,- 占4个字符,总共36个字符,当我们运行上面的程序时,实际上会调用 UUID
哪些方法呢?具体如下:
那么 UUID
是如何生成的呢?32个字符又分别代表什么含义呢?下面通过具体的源码来了解一下。
1、UUID 类定义
UUID
类实现了 Serializable
和 Comparable
接口,其定义如下:
Serializable
:它是一个标记接口,没有任何方法定义,用于对象的序列化;Comparable
:该接口只有一个compareTo
方法,通常用于对实现它的类的对象进行比较大小;
2、成员变量
UUID
类中定义了2个成员变量,分别代表最高有效64位和最低有效64位,如下:
mostSigBits
和 leastSigBits
它们是构成 UUID
标识符的重要组成部分。
3、构造函数
UUID
类提供了 2 个构造函数,其定义如下:
在构造函数中,主要是给成员变量 mostSigBits
和 leastSigBits
赋值,虽然 UUID
提供了 public
构造函数,但是在平时开发中,可能很少直接通过构造函数来创建 UUID
对象,更多的是使用 randomUUID()
方法,下面通过断点方式来看一下这个私有构造函数计算出的 mostSigBits
和 leastSigBits
具体值是多少,如下:
4、方法
UUID
类中的方法主要分为静态方法和实例方法,其中静态方法主要用于创建 UUID
实例的,而实例方法主要用于获取 UUID
中的一些基本信息,比如版本号、时间戳、时钟序列等。
4.1 静态方法 - randomUUID()
randomUUID()
方法可能是使用最多的一个方法,从实现可以看出,首先它通过内部静态类 Holder
获取了一个随机 SecureRandom
对象,主要用于产生随机数,Holder
类定义如下:
4.2 静态方法 - nameUUIDFromBytes()
nameUUIDFromBytes()
方法可以通过一个字节数组来创建 UUID
,首先会通过 MD5
摘要算法对字节数组进行加密转换,得到一个长度为 16 的新字节数组,然后使用新的字节数组构建 UUID
,该方法种会设置版本号为 3,而通过 randomUUID()
方法设置的版本号为 4.
4.3 静态方法 - fromString()
除了上面的可以通过字节数组构建 UUID
外,还可以直接通过字符串来构建,但是不是随便的字符串都可以,而是需要和 UUID.toString()
方法得到的字符串格式一致,也就是使用 -
进行分割时,必须得到长度为 5 的字符串数组,否则就会抛出 IllegalArgumentException
异常,然后根据分割的值来计算 mostSigBits
和 leastSigBits
的值,最后再通过 mostSigBits
和 leastSigBits
构建 UUID
对象。
4.4 实例方法
UUID
类提供的实例方法,主要有以下这些:
version()
: 获取当前UUID
的版本信息;variant()
:获取当前UUID
的变体编号;timestamp()
:获取当前UUID
的时间戳;clockSequence()
:获取当前UUID
的时钟序列值;node()
:获取当前UUID
的节点值;toString()
:将UUID
对象转换为字符串,通过这个方法就可以了解UUID
的构成;hashCode()
:获取当前UUID
的哈希值;equals(Object obj)
:用于比较两个UUID
对象是否相同;compareTo(UUID val)
:比较两个UUID
对象值的大小;
(1)基本信息方法
对于版本号和变体编号信息,是所有 UUID
通用的,而对于基于时间的 UUID
,则可以调用下面的 3 个方法获取时间相关的信息,如下:
(2)toString() 方法
通过 toString()
方法,可以得知 UUID
字符串的具体构成,主要是通过 mostSigBits
和 leastSigBits
进行变换得到的,digits()
方法定义如下:
UUID
的构成主要分为以下的几个:
通过上面的信息可以看出,UUID
由 时间低位
+ 时间中位
+ 时间高位和版本号
+ 变体编号和序列号
+ 节点值
五个部分组成的,可以看一个具体的值
(3)其他方法
对于比较两个 UUID
是否相同或者是否相等,都是直接比较 mostSigBits
和 leastSigBits
的值。
5、测试验证
下面通过 3 种不同的方式来创建 UUID
实例,同时输出基本信息。
运行程序,输出信息如下:
如果直接对上面的创建的 UUID
调用时间相关方法,则会抛出 UnsupportedOperationException
异常,测试代码如下:
输出的错误信息如下:
通过之前的源码分析可以知道,timestamp()
、clockSequence()
、node()
方法必须是基于时间的 UUID
才能调用,基于时间的 UUID
的版本号为 1
,而上面的 uuid
、uuid1
、uuid2
都不是基于时间的,所以会抛出异常。
边栏推荐
- 「业务架构」介绍BPMN第二部分-泳道
- Spss-多元回归案例实操
- Emulate stm32 directly with proteus - the programmer can be completely discarded
- 第二十二章 源代码文件 REST API 参考(四)
- POJ 3101 Astronomy (Mathematics)
- HCIP ---- VLAN
- 第2章-矩阵及其运算-矩阵创建(1)
- OSSCore 开源解决方案介绍
- Gold, nine, silver and ten job-hopping seasons: technical interview questions and answers on Alibaba, Baidu, JD.com, and Meituan
- 建校仅11年就入选“双一流” ,这所高校是凭什么做到的?
猜你喜欢
越折腾越好用的 3 款开源 APP
OneFlow source code parsing: operator instructions executed in a virtual machine
Weilai-software development engineer side record
Short video software development - how to break the platform homogenization
Some tips for using Unsafe
短视频软件开发——平台同质化如何破局
使用cpolar远程连接群晖NAS(升级固定链接2)
ENVI 5.3软件安装包和安装教程
STM32封装ESP8266一键配置函数:实现实现AP模式和STA模式切换、服务器与客户端创建
振弦传感器及核心VM系列振弦采集模块
随机推荐
GPU加速Pinterest推荐模型,参数量增加100倍,用户活跃度提高16%
GPU accelerated Pinterest recommendation model, the number of parameters increased by 100 times, and the user activity increased by 16%
chart.js horizontal column chart plugin
Unsafe的一些使用技巧
EasyCVR级联时,修改下级平台名称将不同步至上级平台
FastReport.Net 2022.2.17 Crack
什么是幂等性?四种接口幂等性方案详解!
从产品维度来看 我们为什么不能完全信任Layer2?
第5章相似矩阵及二次型(4)
blocking non-blocking poll mechanism asynchronous
YTU 2894: G--我要去内蒙古大草原
组合模式:Swift 实现
第3章-线性方程组(3)
Mobile and PC compatible loading and toast message plugins
flask-restplus接口地址404问题
OSSCore 开源解决方案介绍
关于“码农”的一点自嘲解构
STM32封装ESP8266一键配置函数:实现实现AP模式和STA模式切换、服务器与客户端创建
Network Security Note 6 - Digital Certificates and Public Key Infrastructure
mysql5.7 installation and deployment - yum installation