Protobuf 中的 newBuilder() 是否生成 类 创建一个新的 Java 对象?

Does newBuilder() from Protobuf generated classes create a new Java object?

是否 newBuilder() 创建了一个新的 Java 对象?我的快速测试似乎并非如此。在 2 个不同的对象上调用 .hashcode(),它具有相同的哈希码。

import com.mydomain.proto.users.api.User;

...

User a = User.newBuilder().setUserUuid("1111111111").build();
User b = User.newBuilder().setUserUuid("1111111111").build();

System.out.println("a hashcode: " + a.hashCode());
System.out.println("b hashcode: " + b.hashCode());

// assertNotEquals fails.
assertNotEquals(a.hashCode(), b.hashCode());


将它们打印出来并查看哈希码是否相同,尽管我期待一个新的 Java 对象。

a hashcode: 611667980
b hashcode: 611667980

注意,我们正在使用这个

'com.google.protobuf:protobuf-java-util:3.12.0'

hashcode 和 same (==) 的含义不是双向的。

两个对象是同一个对象,或者拥有相同的内容,应该有相同的哈希码。

共享相同哈希码的两个对象并不意味着它们是同一个对象。

为了测试这个,勾选

System.out.println(a==b);

它将打印false因为它们是不同的对象,即使它们共享相同的哈希码。

Message 的源代码:

Equals 首先检查对象是否确实相同 (==) 。如果不是,检查它们的字段和属性 是否包含相同的值 .

如果两个对象 包含相同的属性和字段

Hashcode 将输出相同的值。 无论它们是否是同一个对象 (other==this)。就像字符串一样。

这就是 Java 对象的 hashCode() 告诉我们的:


字符串示例

String s1 = new String("Yepp");  //hashcode = 2752044
String s2 = new String("Yepp");  //hashcode = 2752044
String s3 = s1;                  //hashcode = 2752044

所有人共享相同的哈希码。但是这里有两个不同的对象: s1/s3s2.

System.out.println(s1==s2);   // false
System.out.println(s1==s3);   // true
System.out.println(s1.hashCode()==s2.hashCode()); //true

这就是为什么使用 == 运算符比较两个字符串时常犯的错误。这不是检查值,而是检查对象引用。

如果 class 覆盖 equals,(就像 Strings 那样),它会告诉你它们是相等的对象:可能和双胞胎一样,但无论如何双胞胎是两个。

System.out.println(s1.equals(s2)); // true 

恢复: 是的,正在创建新对象。里面的值是没有意义的,共享相同的hashcode只是表示它们的内容相同(并且它们的hashcode算法运行良好