java UUID 源码学习
2020年5月14日大约 4 分钟
UUID
我们平时在使用 UUID 的时候觉得非常简单,甚至很多人觉得这没什么技术含量。
那么深入思考一层,UUID 的实现原理是什么?
源码
类声明
public final class UUID implements java.io.Serializable, Comparable {
/**
* Explicit serialVersionUID for interoperability.
*/
private static final long serialVersionUID = -4856846361193249489L;
}
实现了两个常见的接口。
内部变量
/*
* The most significant 64 bits of this UUID.
*
* @serial
*/
private final long mostSigBits;
/*
* The least significant 64 bits of this UUID.
*
* @serial
*/
private final long leastSigBits;
/*
* The random number generator used by this class to create random
* based UUIDs. In a holder class to defer initialization until needed.
*/
private static class Holder {
static final SecureRandom numberGenerator = new SecureRandom();
}
前面2个时位定义。
下面一个 Holder 熟悉单例模式的都知道,这是通过内部静态类,达到单例效果的一种写法。
构造器
/**
* Constructs a new {@code UUID} using the specified data. {@code
* mostSigBits} is used for the most significant 64 bits of the {@code
* UUID} and {@code leastSigBits} becomes the least significant 64 bits of
* the {@code UUID}.
*
* @param mostSigBits
* The most significant bits of the {@code UUID}
*
* @param leastSigBits
* The least significant bits of the {@code UUID}
*/
public UUID(long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
这个构造器非常简单,就是做了下基本属性的初始化。
还有一个私有的构造器,内容如下:
/*
* Private constructor which uses a byte array to construct the new UUID.
*/
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i The UUID string representation is as described by this BNF:
*
* {@code
* UUID = "-" "-"
* "-"
* "-"
*
* time_low = 4*
* time_mid = 2*
* time_high_and_version = 2*
* variant_and_sequence = 2*
* node = 6*
* hexOctet =
* hexDigit =
* "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
* | "a" | "b" | "c" | "d" | "e" | "f"
* | "A" | "B" | "C" | "D" | "E" | "F"
* }
*
* @return A string representation of this {@code UUID}
*/
public String toString() {
return (digits(mostSigBits >> 32, 8) + "-" +
digits(mostSigBits >> 16, 4) + "-" +
digits(mostSigBits, 4) + "-" +
digits(leastSigBits >> 48, 4) + "-" +
digits(leastSigBits, 12));
}
- digits()
这里就是把数字转换为 16 进制
/** Returns val represented by the specified number of hex digits. */
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
感触
看完之后,是不是觉得并没有得到精髓呢?
我觉得算法的原理不清楚,单独看了下源码,实际上有些问题还是没有解决。
为什么 UUID 可以保证唯一性?
如何实现自己的,位数更少的 id 算法?
关于这部分将在其他文章中进行补充完善。
拓展阅读
参考资料
jdk8 源码
贡献者
binbin.hou