Exclude static fields from reflection based builder
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137031 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b1ad52a457
commit
aea52bdea5
|
@ -99,7 +99,7 @@ import org.apache.commons.lang.NumberUtils;
|
||||||
* </pre>
|
* </pre>
|
||||||
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
|
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
|
||||||
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
||||||
* @version $Id: CompareToBuilder.java,v 1.1 2002/09/15 10:25:22 scolebourne Exp $
|
* @version $Id: CompareToBuilder.java,v 1.2 2002/09/17 22:06:37 scolebourne Exp $
|
||||||
*/
|
*/
|
||||||
public class CompareToBuilder {
|
public class CompareToBuilder {
|
||||||
/**
|
/**
|
||||||
|
@ -128,9 +128,10 @@ public class CompareToBuilder {
|
||||||
* It is also not as efficient as testing explicitly.
|
* It is also not as efficient as testing explicitly.
|
||||||
* Transient members will be not be tested, as they are likely derived
|
* Transient members will be not be tested, as they are likely derived
|
||||||
* fields, and not part of the value of the object.
|
* fields, and not part of the value of the object.
|
||||||
* @param lhs - Left Hand Side
|
* Static fields will not be tested.
|
||||||
* @param rhs - Right Hand Side
|
* @param lhs Left Hand Side
|
||||||
* @return int - a negative integer, zero, or a positive integer as this
|
* @param rhs Right Hand Side
|
||||||
|
* @return int a negative integer, zero, or a positive integer as this
|
||||||
* object is less than, equal to, or greater than the specified object.
|
* object is less than, equal to, or greater than the specified object.
|
||||||
* @throws ClassCastException - if the specified object's type prevents it
|
* @throws ClassCastException - if the specified object's type prevents it
|
||||||
* from being compared to this Object.
|
* from being compared to this Object.
|
||||||
|
@ -149,16 +150,18 @@ public class CompareToBuilder {
|
||||||
* If the TestTransients parameter is set to true, transient members will be
|
* If the TestTransients parameter is set to true, transient members will be
|
||||||
* tested, otherwise they are ignored, as they are likely derived fields, and
|
* tested, otherwise they are ignored, as they are likely derived fields, and
|
||||||
* not part of the value of the object.
|
* not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
*
|
*
|
||||||
* @param lhs - Left Hand Side
|
* @param lhs Left Hand Side
|
||||||
* @param rhs - Right Hand Side
|
* @param rhs Right Hand Side
|
||||||
* @param testTransients - whether to include transient fields
|
* @param testTransients whether to include transient fields
|
||||||
* @return int - a negative integer, zero, or a positive integer as this
|
* @return int - a negative integer, zero, or a positive integer as this
|
||||||
* object is less than, equal to, or greater than the specified object.
|
* object is less than, equal to, or greater than the specified object.
|
||||||
* @throws ClassCastException - if the specified object's type prevents it
|
* @throws ClassCastException - if the specified object's type prevents it
|
||||||
* from being compared to this Object.
|
* from being compared to this Object.
|
||||||
*/
|
*/
|
||||||
public static int reflectionCompare(Object lhs, Object rhs, boolean testTransients) {
|
public static int reflectionCompare(Object lhs, Object rhs,
|
||||||
|
boolean testTransients) {
|
||||||
if (lhs == rhs) {
|
if (lhs == rhs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -175,12 +178,14 @@ public class CompareToBuilder {
|
||||||
for (int i = 0; i < fields.length && compareToBuilder.comparison == 0; ++i) {
|
for (int i = 0; i < fields.length && compareToBuilder.comparison == 0; ++i) {
|
||||||
Field f = fields[i];
|
Field f = fields[i];
|
||||||
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
||||||
try {
|
if ( !Modifier.isStatic(f.getModifiers())) {
|
||||||
compareToBuilder.append(f.get(lhs), f.get(rhs));
|
try {
|
||||||
} catch (IllegalAccessException e) {
|
compareToBuilder.append(f.get(lhs), f.get(rhs));
|
||||||
//this can't happen. Would get a Security exception instead
|
} catch (IllegalAccessException e) {
|
||||||
//throw a runtime exception in case the impossible happens.
|
//this can't happen. Would get a Security exception instead
|
||||||
throw new InternalError("Unexpected IllegalAccessException");
|
//throw a runtime exception in case the impossible happens.
|
||||||
|
throw new InternalError("Unexpected IllegalAccessException");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ import java.lang.reflect.Modifier;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
|
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
|
||||||
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
||||||
* @version $Id: EqualsBuilder.java,v 1.1 2002/09/12 22:00:00 scolebourne Exp $
|
* @version $Id: EqualsBuilder.java,v 1.2 2002/09/17 22:06:38 scolebourne Exp $
|
||||||
*/
|
*/
|
||||||
public class EqualsBuilder {
|
public class EqualsBuilder {
|
||||||
/**
|
/**
|
||||||
|
@ -129,11 +129,12 @@ public class EqualsBuilder {
|
||||||
* that it will throw a security exception if run under a security manger, if
|
* that it will throw a security exception if run under a security manger, if
|
||||||
* the permissions are not set up.
|
* the permissions are not set up.
|
||||||
* It is also not as efficient as testing explicitly.
|
* It is also not as efficient as testing explicitly.
|
||||||
* Transient members will be not be tested, as they are likely derived
|
* Transient members will be not be tested, as they are likely derived
|
||||||
* fields, and not part of the value of the object.
|
* fields, and not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
*
|
*
|
||||||
* @param lhs - Left Hand Side
|
* @param lhs Left Hand Side
|
||||||
* @param rhs - Right Hand Side
|
* @param rhs Right Hand Side
|
||||||
* @return boolean - if the two objects have tested equals.
|
* @return boolean - if the two objects have tested equals.
|
||||||
*/
|
*/
|
||||||
public static boolean reflectionEquals(Object lhs, Object rhs) {
|
public static boolean reflectionEquals(Object lhs, Object rhs) {
|
||||||
|
@ -150,13 +151,15 @@ public class EqualsBuilder {
|
||||||
* If the TestTransients parameter is set to true, transient members will be
|
* If the TestTransients parameter is set to true, transient members will be
|
||||||
* tested, otherwise they are ignored, as they are likely derived fields, and
|
* tested, otherwise they are ignored, as they are likely derived fields, and
|
||||||
* not part of the value of the object.
|
* not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
*
|
*
|
||||||
* @param lhs - Left Hand Side
|
* @param lhs Left Hand Side
|
||||||
* @param rhs - Right Hand Side
|
* @param rhs Right Hand Side
|
||||||
* @param testTransients - whether to include transient fields
|
* @param testTransients whether to include transient fields
|
||||||
* @return boolean - if the two objects have tested equals.
|
* @return boolean - if the two objects have tested equals.
|
||||||
*/
|
*/
|
||||||
public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients) {
|
public static boolean reflectionEquals(Object lhs, Object rhs,
|
||||||
|
boolean testTransients) {
|
||||||
if (lhs == rhs) {
|
if (lhs == rhs) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -173,12 +176,14 @@ public class EqualsBuilder {
|
||||||
for (int i = 0; i < fields.length && equalsBuilder.isEquals; ++i) {
|
for (int i = 0; i < fields.length && equalsBuilder.isEquals; ++i) {
|
||||||
Field f = fields[i];
|
Field f = fields[i];
|
||||||
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
||||||
try {
|
if (!Modifier.isStatic(f.getModifiers())) {
|
||||||
equalsBuilder.append(f.get(lhs), f.get(rhs));
|
try {
|
||||||
} catch (IllegalAccessException e) {
|
equalsBuilder.append(f.get(lhs), f.get(rhs));
|
||||||
//this can't happen. Would get a Security exception instead
|
} catch (IllegalAccessException e) {
|
||||||
//throw a runtime exception in case the impossible happens.
|
//this can't happen. Would get a Security exception instead
|
||||||
throw new InternalError("Unexpected IllegalAccessException");
|
//throw a runtime exception in case the impossible happens.
|
||||||
|
throw new InternalError("Unexpected IllegalAccessException");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ import java.lang.reflect.Modifier;
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
||||||
* @version $Id: HashCodeBuilder.java,v 1.1 2002/09/12 21:59:01 scolebourne Exp $
|
* @version $Id: HashCodeBuilder.java,v 1.2 2002/09/17 22:06:38 scolebourne Exp $
|
||||||
*/
|
*/
|
||||||
public class HashCodeBuilder {
|
public class HashCodeBuilder {
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ public class HashCodeBuilder {
|
||||||
* It is also not as efficient as testing explicitly.
|
* It is also not as efficient as testing explicitly.
|
||||||
* Transient members will be not be used, as they are likely derived
|
* Transient members will be not be used, as they are likely derived
|
||||||
* fields, and not part of the value of the object.
|
* fields, and not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
* This constructor uses two hard coded choices for the constants needed
|
* This constructor uses two hard coded choices for the constants needed
|
||||||
* to build a hash code.
|
* to build a hash code.
|
||||||
*
|
*
|
||||||
|
@ -176,33 +177,6 @@ public class HashCodeBuilder {
|
||||||
return reflectionHashCode(object, false);
|
return reflectionHashCode(object, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method uses reflection to build a valid hash code.
|
|
||||||
* <p>
|
|
||||||
* It uses Field.setAccessible to gain access to private fields. This means
|
|
||||||
* that it will throw a security exception if run under a security manger, if
|
|
||||||
* the permissions are not set up.
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @param initialNonZeroOddNumber
|
|
||||||
* @param multiplierNonZeroOddNumber
|
|
||||||
* @param object the object to create a hash code for
|
|
||||||
* @return int hash code
|
|
||||||
* @throws IllegalArgumentException if the object is null
|
|
||||||
* @throws IllegalArgumentException if the number is zero or even
|
|
||||||
*/
|
|
||||||
public static int reflectionHashCode(
|
|
||||||
int initialNonZeroOddNumber, int multiplierNonZeroOddNumber,
|
|
||||||
Object object) {
|
|
||||||
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method uses reflection to build a valid hash code.
|
* This method uses reflection to build a valid hash code.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -213,6 +187,7 @@ public class HashCodeBuilder {
|
||||||
* If the TestTransients parameter is set to true, transient members will be
|
* If the TestTransients parameter is set to true, transient members will be
|
||||||
* tested, otherwise they are ignored, as they are likely derived fields, and
|
* tested, otherwise they are ignored, as they are likely derived fields, and
|
||||||
* not part of the value of the object.
|
* not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
* This constructor uses two hard coded choices for the constants needed
|
* This constructor uses two hard coded choices for the constants needed
|
||||||
* to build a hash code.
|
* to build a hash code.
|
||||||
*
|
*
|
||||||
|
@ -225,6 +200,34 @@ public class HashCodeBuilder {
|
||||||
return reflectionHashCode(17, 37, object, testTransients);
|
return reflectionHashCode(17, 37, object, testTransients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method uses reflection to build a valid hash code.
|
||||||
|
* <p>
|
||||||
|
* It uses Field.setAccessible to gain access to private fields. This means
|
||||||
|
* that it will throw a security exception if run under a security manger, if
|
||||||
|
* the permissions are not set up.
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param initialNonZeroOddNumber
|
||||||
|
* @param multiplierNonZeroOddNumber
|
||||||
|
* @param object the object to create a hash code for
|
||||||
|
* @return int hash code
|
||||||
|
* @throws IllegalArgumentException if the object is null
|
||||||
|
* @throws IllegalArgumentException if the number is zero or even
|
||||||
|
*/
|
||||||
|
public static int reflectionHashCode(
|
||||||
|
int initialNonZeroOddNumber, int multiplierNonZeroOddNumber,
|
||||||
|
Object object) {
|
||||||
|
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method uses reflection to build a valid hash code.
|
* This method uses reflection to build a valid hash code.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -235,6 +238,7 @@ public class HashCodeBuilder {
|
||||||
* If the TestTransients parameter is set to true, transient members will be
|
* If the TestTransients parameter is set to true, transient members will be
|
||||||
* tested, otherwise they are ignored, as they are likely derived fields, and
|
* tested, otherwise they are ignored, as they are likely derived fields, and
|
||||||
* not part of the value of the object.
|
* not part of the value of the object.
|
||||||
|
* Static fields will not be tested.
|
||||||
* <p>
|
* <p>
|
||||||
* Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
|
* Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
|
||||||
* these should be different for each class, however this is not vital.
|
* these should be different for each class, however this is not vital.
|
||||||
|
@ -261,12 +265,14 @@ public class HashCodeBuilder {
|
||||||
for (int i = 0; i < fields.length; ++i) {
|
for (int i = 0; i < fields.length; ++i) {
|
||||||
Field f = fields[i];
|
Field f = fields[i];
|
||||||
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
|
||||||
try {
|
if (!Modifier.isStatic(f.getModifiers())) {
|
||||||
hashCodeBuilder.append(f.get(object));
|
try {
|
||||||
} catch (IllegalAccessException e) {
|
hashCodeBuilder.append(f.get(object));
|
||||||
//this can't happen. Would get a Security exception instead
|
} catch (IllegalAccessException e) {
|
||||||
//throw a runtime exception in case the impossible happens.
|
//this can't happen. Would get a Security exception instead
|
||||||
throw new InternalError("Unexpected IllegalAccessException");
|
//throw a runtime exception in case the impossible happens.
|
||||||
|
throw new InternalError("Unexpected IllegalAccessException");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue