我解釋說ToStringBuilder將十六進制格式的身份哈希碼添加到其輸出中。 在本文中,我將更深入地研究ToStringBuilder
對以十六進制格式顯示的身份哈希碼的使用。 甚至那些不使用ToStringBuilder
也可能會發現此信息很有用,因為Java的標準Object.toString()也使用有效表示其身份哈希碼的十六進制表示形式。
我將從使用ToStringBuilder
一個非常簡單的Java示例開始。 本示例使用下面顯示的三個Java類( Person.java
, Employee.java
和Main.java
)。
人.java
package dustin.examples;import org.apache.commons.lang.builder.ToStringBuilder;/*** A simple representation of a Person intended only to demonstrate Apache* Commons ToStringBuilder.* * @author Dustin*/
public class Person
{/** Person's last name (surname). */protected final String lastName;/** Person's first name. */protected final String firstName;/*** Parameterized constructor for obtaining an instance of Person.* * @param newLastName Last name of new Person instance.* @param newFirstName First name of new Person instance.*/public Person(final String newLastName, final String newFirstName){this.lastName = newLastName;this.firstName = newFirstName;}/*** Provide String representation of this Person instance.* @return My String representation.*/@Overridepublic String toString(){final ToStringBuilder builder = new ToStringBuilder(this);builder.append("First Name", this.firstName);builder.append("Last Name", this.lastName);return builder.toString();}
}
Employee.java
package dustin.examples;import java.util.Objects;
import org.apache.commons.lang.builder.ToStringBuilder;/*** Simple class intended to demonstrate ToStringBuilder.* * @author Dustin*/
public class Employee extends Person
{/** Employee ID. */private final String employeeId;/*** Parameterized constructor for obtaining an instance of Employee.* * @param newLastName Last name of the employee.* @param newFirstName First name of the employee. * @param newId Employee's employee ID.*/public Employee(final String newLastName, final String newFirstName, final String newId){super(newLastName, newFirstName);this.employeeId = newId;}/*** Provide String representation of me.** @return My String representation.*/@Overridepublic String toString(){final ToStringBuilder builder = new ToStringBuilder(this);builder.appendSuper(super.toString());builder.append("Employee ID", this.employeeId);return builder.toString();}/*** Simple object equality comparison method.* * @param obj Object to be compared to me for equality.* @return {@code true} if the provided object and I are considered equal.*/@Overridepublic boolean equals(Object obj){if (obj == null){return false;}if (getClass() != obj.getClass()){return false;}final Employee other = (Employee) obj;if (!Objects.equals(this.employeeId, other.employeeId)){return false;}return true;}/*** Hash code for this instance.* * @return My hash code.*/@Overridepublic int hashCode(){int hash = 3;hash = 19 * hash + Objects.hashCode(this.employeeId);return hash;}
}
Main.java(版本1)
package dustin.examples;import static java.lang.System.out;/*** Simple class enabling demonstration of ToStringBuilder.* * @author Dustin*/
public class Main
{/*** Main function for running Java examples with ToStringBuilder.* * @param args the command line arguments*/public static void main(String[] args){final Person person = new Person("Washington", "Willow");out.println(person);final Employee employee = new Employee("Lazentroph", "Frank", "56");out.println(employee);}
}
上面的例子很簡單,其輸出如下所示:

上面描述的輸出顯示了為ToStringBuilder
生成的兩個實例的輸出所打印的字符串。 Person
類實例的字符串表示形式包括字符串“ 1f5d386”,而Employee
類實例的字符串表示形式包括字符串“ 1c9b9ca”。 這些字符串是每個對象的身份哈希碼的十六進制表示形式 。
字符串“ 1f5d386”和“ 1c9b9ca”看起來不像我們中的很多人習慣的整數哈希碼,因為它們以十六進制表示。 Integer.toHexString(int)方法[自JDK 1.0.2起可用]是一種方便的方法,用于以十六進制格式打印整數,可用于轉換“常規”哈希碼以查看它們是否與ToStringBuilder
生成的哈希碼匹配。 我已經在Main
類的新版本中的實例的哈希碼上添加了對該方法的調用。
Main.java(版本2)
package dustin.examples;import static java.lang.System.out;/*** Simple class enabling demonstration of ToStringBuilder.* * @author Dustin*/
public class Main
{/*** Main function for running Java examples with ToStringBuilder.* * @param args the command line arguments*/public static void main(String[] args){final Person person = new Person("Washington", "Willow");out.println(person);out.println("\tHash Code (ten): " + person.hashCode());out.println("\tHash Code (hex): " + Integer.toHexString(person.hashCode()));final Employee employee = new Employee("Lazentroph", "Frank", "56");out.println(employee);out.println("\tHash Code (ten): " + employee.hashCode());out.println("\tHash Code (hex): " + Integer.toHexString(employee.hashCode()));}
}
執行以上操作會導致以下輸出:

如輸出所示, Person
實例的哈希碼的十六進制表示確實與該實例的ToStringBuilder
生成的String中顯示的匹配。 但是,不能對Employee
實例說同樣的話。 區別在于Person
類不會覆蓋hashCode()方法 ,因此默認情況下使用身份哈希碼,而Employee
類卻覆蓋其自己的hashCode()
(因此與身份哈希碼不同)。
Main
的第三個版本使用System.identityHashCode(Object)輸出身份哈希碼[在我的博客文章Java的System.identityHashCode中進一步詳細討論]。
Main.java(版本3)
package dustin.examples;import static java.lang.System.out;/*** Simple class enabling demonstration of ToStringBuilder.* * @author Dustin*/
public class Main
{/*** Main function for running Java examples with ToStringBuilder.* * @param args the command line arguments*/public static void main(String[] args){final Person person = new Person("Washington", "Willow");out.println(person);out.println("\tHash Code (ten): " + person.hashCode());out.println("\tHash Code (hex): " + Integer.toHexString(person.hashCode()));out.println("\t\tIdentity Hash (ten): " + System.identityHashCode(person));out.println("\t\tIdentity Hash (hex): " + Integer.toHexString(System.identityHashCode(person)));final Employee employee = new Employee("Lazentroph", "Frank", "56");out.println(employee);out.println("\tHash Code (ten): " + employee.hashCode());out.println("\tHash Code (hex): " + Integer.toHexString(employee.hashCode()));out.println("\t\tIdentity Hash (ten): " + System.identityHashCode(employee));out.println("\t\tIdentity Hash (hex): " + Integer.toHexString(System.identityHashCode(employee)));}
現在,我們可以將身份哈希碼與ToStringBuilder
生成的字符串進行比較。

最后一個示例明確地說明ToStringBuilder
在其生成的輸出中包括系統標識哈希碼的十六進制表示。 如果要使用覆蓋的哈希碼而不是標識哈希碼的十六進制表示形式,則可以使用ToStringStyle的實例(通常是StandardToStringStyle的實例),并且可以使用false
參數調用方法setUseIdentityHashCode(boolean) 。 此實例ToStringStyle
然后可以被傳遞到ToStringBuilder.setDefaultStyle(ToStringStyle)方法。
附帶說明一下,上面顯示的Employee
類中的equals(Object)和hashCode()
方法是由NetBeans 7.1自動生成的。 我很高興地看到,該項目的Java源代碼版本指定為JDK 1.7 ,這兩種方法的自動生成利用了Objects類。
在本文中,我一直使用ToStringBuilder
生成的輸出來促進對身份哈希碼的十六進制表示形式的討論,但是我可以簡單地將JDK自己內置的“默認” Object.toString()實現用于同一目的。 實際上,Javadoc甚至宣傳了這一點:
Object
類的toString
方法返回一個字符串,該字符串包括該對象是其實例的類的名稱,符號字符“ @”以及該對象的哈希碼的無符號十六進制表示形式。 換句話說,此方法返回的字符串等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
我沒有使用此示例開始的唯一原因是,我幾乎總是在類中重寫toString()方法 ,并且未獲得此“默認”實現。 但是,當我使用ToStringBuilder
實現重寫的toString()
方法時,確實看到了這些十六進制表示形式。 我可能會增加對Objects.toString()的使用,從而減少對ToStringBuilder
使用。
我們中的許多人在日常的Java工作中都不會考慮十六進制表示形式或標識哈希碼。 在此博客文章中,我以ToStringBuilder
的輸出為借口來更仔細地研究這兩個概念。 在此過程中,我還簡要介紹了Integer.toHexString(Object)
方法,該方法對于以十六進制表示形式打印數字很有用。 了解Java對十六進制表示法的支持很重要,因為Java確實會出現在toString()輸出 , 顏色標簽 , 內存地址和其他地方。
參考: ToString: JCG合作伙伴提供 的身份哈希碼的十六進制表示形式 ? 實際事件啟發博客中的達斯汀·馬克思。
翻譯自: https://www.javacodegeeks.com/2012/03/tostring-hexadecimal-representation-of.html