Я объяснил, что ToStringBuilder добавляет к выводу хеш-код идентичности в шестнадцатеричном формате. В этой статье я более подробно рассмотрю использование ToStringBuilder хеш-кода идентификатора, представленного в шестнадцатеричном формате. Даже те, кто не использует ToStringBuilder могут найти эту информацию полезной, так как стандартный Java Object.toString () также использует шестнадцатеричное представление того, что фактически является его хэш-кодом идентичности.
Я начну с очень простого примера Java с использованием ToStringBuilder . В этом примере используются три Java-класса ( Person.java , Employee.java и Main.java ), которые показаны далее.
Person.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
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. */ @Override public 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
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
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. */ @Override public 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. */ @Override public 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. */ @Override public int hashCode() { int hash = 3; hash = 19 * hash + Objects.hashCode(this.employeeId); return hash; }} |
Main.java (Версия 1)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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); }} |
Приведенный выше пример прост и его вывод показан ниже:
Вывод, изображенный выше, показывает строку String, напечатанную для вывода обоих экземпляров, сгенерированного ToStringBuilder . Представление String экземпляра класса Person включает строку «1f5d386», а представление String экземпляра класса Employee включает строку «1c9b9ca». Эти строки являются шестнадцатеричным представлением хеш-кода каждого объекта.
Строки «1f5d386» и «1c9b9ca» не похожи на целочисленные хеш-коды, которые многие из нас привыкли видеть из-за их шестнадцатеричного представления. Методы Integer.toHexString (int) [доступны с JDK 1.0.2] — это удобный метод для печати целого числа в шестнадцатеричном формате, и его можно использовать для преобразования «обычных» хеш-кодов, чтобы увидеть, соответствуют ли они тем, которые сгенерированы ToStringBuilder . Я добавил вызовы к этому методу в хэш-кодах экземпляров в новой версии класса Main .
Main.java (версия 2)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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 созданной ToStringBuilder для этого экземпляра. Однако этого нельзя сказать о экземпляре Employee . Разница в том, что класс Person не переопределяет метод hashCode () и поэтому использует хеш-код идентификатора по умолчанию, в то время как класс Employee переопределяет свой собственный hashCode() (и, следовательно, отличается от хэш-кода идентификатора).
Третья версия Main выводит хэш-код идентификатора с использованием System.identityHashCode (Object) [более подробно обсуждается в моем блоге Java System.identityHashCode ].
Main.java (Версия 3)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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 ), а метод setUseIdentityHashCode (boolean) можно вызвать с параметром false . Этот экземпляр ToStringStyle затем может быть передан методу ToStringBuilder.setDefaultStyle (ToStringStyle) .
Примечательно, что методы equals (Object) и hashCode() в классе Employee показанном выше, были автоматически созданы NetBeans 7.1 . Я был рад видеть, что с моей исходной версией Java для этого проекта, определенной как JDK 1.7 , это автоматическое создание этих двух методов использовало преимущества класса Objects .
В этом посте я использовал вывод, сгенерированный ToStringBuilder чтобы облегчить обсуждение шестнадцатеричных представлений идентификаторов хеш-кодов, но я мог бы просто использовать собственную встроенную в JDK реализацию Object.toString () по умолчанию для той же цели. На самом деле, Javadoc даже рекламирует это:
Метод
toStringдля классаObjectвозвращает строку, состоящую из имени класса, экземпляром которого является объект, символа знака «@» и шестнадцатеричного представления без знака хеш-кода объекта. Другими словами, этот метод возвращает строку, равную значению:
getClass().getName() + '@' + Integer.toHexString(hashCode())
Единственная причина, по которой я не использовал этот пример для начала, состоит в том, что я почти всегда переопределяю метод toString () в своих классах и не получаю эту реализацию «по умолчанию». Однако, когда я использую ToStringBuilder для реализации своих переопределенных методов toString() , я вижу эти шестнадцатеричные представления. Я могу уменьшить использование ToStringBuilder мере увеличения использования Objects.toString () .
Многие из нас не думают о шестнадцатеричных представлениях или хэш-кодах идентичности в нашей повседневной работе на Java. В этом сообщении в блоге я использовал вывод ToStringBuilder в качестве предлога для того, чтобы взглянуть немного ближе на эти две концепции. Попутно я также кратко рассмотрел метод Integer.toHexString(Object) , который полезен для печати чисел в их шестнадцатеричном представлении. Знание о поддержке Java шестнадцатеричного представления важно, потому что оно отображается в выводе toString () , при маркировке цветов , адресов памяти и в других местах.
Ссылка: ToString: шестнадцатеричное представление идентификационных хеш-кодов от нашего партнера JCG


