我创建了两个java.util.UUID
实例,如下所示。一个是从UUID.randomUUID()
创建的,另一个是相同的,但在开头前面附加了一些数字。当使用UUID.equals
方法比较它们时,它返回true
:
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.fromString("12345"+uuid1.toString());
System.out.println(uuid1.equals(uuid2)); // this gives true.
我认为添加的数字被丢弃,并且都给出了相同的 UUID 字符串值。为什么会这样?
在 UUID.fromString(...) 方法中,你有这个:
public static UUID fromString(String name) {
String[] components = name.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: "+name);
for (int i=0; i<5; i++)
components[i] = "0x"+components[i];
long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue();
return new UUID(mostSigBits, leastSigBits);
}
它做的第一件事是将 UUID 的各个部分分成组件,然后它将创建两个长整型。在这里,您仅通过添加前导字符更改了 UUID 的第一个组成部分,例如 UUID 字符串是">12345894ff97a-039b-47fe-8a72-950b7766d50c"。所以第一个组件是">12345894ff97a",什么时候它会做
long mostSigBits = Long.decode(components[0]).longValue();
然后你会有"320256540146042",实际的十六进制表示是">12345894ff97a",然后你有一个位运算,将长 16 位向左移动:
mostSigBits <<= 16;
这将导致"2541588541301456896",实际的十六进制表示为">2345894ff97a0000"(我们移动了 16 位,所以 4 个十六进制字符),你开始看到发生了什么,看到长格式只有 64 位,所以当移动位时,一些位丢失,这里第一个字符"1"丢失。之后,在释放的空间中,它将添加第二个组件:
mostSigBits |= Long.decode(components[1]).longValue();
这将导致"2541588541301457819",实际的十六进制表示为">2345894ff97a039b",然后它将再次将长 16 位向左移动:
mostSigBits <<= 16;
这将导致"-8552342864911466496",实际的十六进制表示形式是"894ff97a039b0000",并且由于 64 位大小较长,您的前导字符都丢失了。
我不需要解释该方法的其余部分(最后大多数SigBits是"894ff97a039b47fe",最小SigBits是"8a72950b7766d50c"),你已经可以理解,在调用UUID.fromString(..)时,添加到UUID的任何前导字符都将丢失,因为只考虑最后8个十六进制字符(32位),其余的将丢失。
因为您没有创建两个不同的 UUID。
UUID.fromString("12345"+uuid1.toString());
没有意义:UUID.fromString(String)
要求传递的 String 遵循UUID.toString()
中所述的"字符串标准表示形式"。请参阅 UUID.fromString() 和 UUID.toString()。
我想知道为什么你不会得到例外,但我想你的前几个字符被忽略了。