Alternatively, there is a method that uses reflection to determine the fields to test. Because these fields are
usually private, the method, reflectionHashCode, uses AccessibleObject.setAccessible
to change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions
are set up correctly. It is also slower than testing explicitly.
| Method from org.apache.commons.lang.builder.HashCodeBuilder Detail: |
public HashCodeBuilder append(boolean value) {
iTotal = iTotal * iConstant + (value ? 0 : 1);
return this;
}
Append a hashCode for a boolean.
This adds iConstant * 1 to the hashCode and not a 1231 or
1237 as done in java.lang.Boolean. This is in accordance with the Effective Java
design.
|
public HashCodeBuilder append(boolean[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(byte value) {
iTotal = iTotal * iConstant + value;
return this;
}
|
public HashCodeBuilder append(byte[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(char value) {
iTotal = iTotal * iConstant + value;
return this;
}
|
public HashCodeBuilder append(char[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(double value) {
return append(Double.doubleToLongBits(value));
}
|
public HashCodeBuilder append(double[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(float value) {
iTotal = iTotal * iConstant + Float.floatToIntBits(value);
return this;
}
|
public HashCodeBuilder append(float[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(int value) {
iTotal = iTotal * iConstant + value;
return this;
}
|
public HashCodeBuilder append(int[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(long value) {
iTotal = iTotal * iConstant + ((int) (value ^ (value > > 32)));
return this;
}
|
public HashCodeBuilder append(long[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(Object object) {
if (object == null) {
iTotal = iTotal * iConstant;
} else {
// 'Switch' on type of array, to dispatch to the correct handler
// This handles multi dimensional arrays
if (object instanceof long[]) {
append((long[]) object);
} else if (object instanceof int[]) {
append((int[]) object);
} else if (object instanceof short[]) {
append((short[]) object);
} else if (object instanceof char[]) {
append((char[]) object);
} else if (object instanceof byte[]) {
append((byte[]) object);
} else if (object instanceof double[]) {
append((double[]) object);
} else if (object instanceof float[]) {
append((float[]) object);
} else if (object instanceof boolean[]) {
append((boolean[]) object);
} else if (object instanceof Object[]) {
// Not an array of primitives
append((Object[]) object);
} else {
iTotal = iTotal * iConstant + object.hashCode();
}
}
return this;
}
|
public HashCodeBuilder append(Object[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder append(short value) {
iTotal = iTotal * iConstant + value;
return this;
}
|
public HashCodeBuilder append(short[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (int i = 0; i < array.length; i++) {
append(array[i]);
}
}
return this;
}
|
public HashCodeBuilder appendSuper(int superHashCode) {
iTotal = iTotal * iConstant + superHashCode;
return this;
}
|
static Set getRegistry() {
return (Set) registry.get();
}
|
static boolean isRegistered(Object value) {
return getRegistry().contains(toIdentityHashCodeInteger(value));
}
Returns true if the registry contains the given object. Used by the reflection methods to avoid
infinite loops.
|
public static int reflectionHashCode(Object object) {
return reflectionHashCode(17, 37, object, false, null, null);
}
This method uses reflection to build a valid hash code.
This constructor uses two hard coded choices for the constants needed to build a hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
Transient members will be not be used, as they are likely derived fields, and not part of the value of the
Object.
Static fields will not be tested. Superclass fields will be included.
|
public static int reflectionHashCode(Object object,
boolean testTransients) {
return reflectionHashCode(17, 37, object, testTransients, null, null);
}
This method uses reflection to build a valid hash code.
This constructor uses two hard coded choices for the constants needed to build a hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
If the TestTransients parameter is set to true, transient members will be tested, otherwise they
are ignored, as they are likely derived fields, and not part of the value of the Object.
Static fields will not be tested. Superclass fields will be included.
|
public static int reflectionHashCode(Object object,
Collection excludeFields) {
return reflectionHashCode(object, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
}
This method uses reflection to build a valid hash code.
This constructor uses two hard coded choices for the constants needed to build a hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
Transient members will be not be used, as they are likely derived fields, and not part of the value of the
Object.
Static fields will not be tested. Superclass fields will be included.
|
public static int reflectionHashCode(Object object,
String[] excludeFields) {
return reflectionHashCode(17, 37, object, false, null, excludeFields);
}
This method uses reflection to build a valid hash code.
This constructor uses two hard coded choices for the constants needed to build a hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
Transient members will be not be used, as they are likely derived fields, and not part of the value of the
Object.
Static fields will not be tested. Superclass fields will be included.
|
public static int reflectionHashCode(int initialNonZeroOddNumber,
int multiplierNonZeroOddNumber,
Object object) {
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null, null);
}
This method uses reflection to build a valid hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
Transient members will be not be used, as they are likely derived fields, and not part of the value of the
Object.
Static fields will not be tested. Superclass fields will be included.
Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
however this is not vital. Prime numbers are preferred, especially for the multiplier.
|
public static int reflectionHashCode(int initialNonZeroOddNumber,
int multiplierNonZeroOddNumber,
Object object,
boolean testTransients) {
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null,
null);
}
This method uses reflection to build a valid hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
If the TestTransients parameter is set to true, transient members will be tested, otherwise they
are ignored, as they are likely derived fields, and not part of the value of the Object.
Static fields will not be tested. Superclass fields will be included.
Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
however this is not vital. Prime numbers are preferred, especially for the multiplier.
|
public static int reflectionHashCode(int initialNonZeroOddNumber,
int multiplierNonZeroOddNumber,
Object object,
boolean testTransients,
Class reflectUpToClass) {
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients,
reflectUpToClass, null);
}
|
public static int reflectionHashCode(int initialNonZeroOddNumber,
int multiplierNonZeroOddNumber,
Object object,
boolean testTransients,
Class reflectUpToClass,
String[] excludeFields) {
if (object == null) {
throw new IllegalArgumentException("The object to build a hash code for must not be null");
}
HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
Class clazz = object.getClass();
reflectionAppend(object, clazz, builder, testTransients, excludeFields);
while (clazz.getSuperclass() != null && clazz != reflectUpToClass) {
clazz = clazz.getSuperclass();
reflectionAppend(object, clazz, builder, testTransients, excludeFields);
}
return builder.toHashCode();
}
This method uses reflection to build a valid hash code.
It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
also not as efficient as testing explicitly.
If the TestTransients parameter is set to true, transient members will be tested, otherwise they
are ignored, as they are likely derived fields, and not part of the value of the Object.
Static fields will not be included. Superclass fields will be included up to and including the specified
superclass. A null superclass is treated as java.lang.Object.
Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
however this is not vital. Prime numbers are preferred, especially for the multiplier.
|
static void register(Object value) {
getRegistry().add(toIdentityHashCodeInteger(value));
}
|
public int toHashCode() {
return iTotal;
}
|
static void unregister(Object value) {
getRegistry().remove(toIdentityHashCodeInteger(value));
}
Unregisters the given object.
Used by the reflection methods to avoid infinite loops.
|