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:
Stephen Colebourne 2002-09-17 22:06:38 +00:00
parent b1ad52a457
commit aea52bdea5
3 changed files with 79 additions and 63 deletions

View File

@ -99,7 +99,7 @@ import org.apache.commons.lang.NumberUtils;
* </pre>
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</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 {
/**
@ -128,9 +128,10 @@ public class CompareToBuilder {
* It is also not as efficient as testing explicitly.
* Transient members will be not be tested, as they are likely derived
* fields, and not part of the value of the object.
* @param lhs - Left Hand Side
* @param rhs - Right Hand Side
* @return int - a negative integer, zero, or a positive integer as this
* Static fields will not be tested.
* @param lhs Left Hand Side
* @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.
* @throws ClassCastException - if the specified object's type prevents it
* 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
* 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.
*
* @param lhs - Left Hand Side
* @param rhs - Right Hand Side
* @param testTransients - whether to include transient fields
* @param lhs Left Hand Side
* @param rhs Right Hand Side
* @param testTransients whether to include transient fields
* @return int - a negative integer, zero, or a positive integer as this
* object is less than, equal to, or greater than the specified object.
* @throws ClassCastException - if the specified object's type prevents it
* 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) {
return 0;
}
@ -175,12 +178,14 @@ public class CompareToBuilder {
for (int i = 0; i < fields.length && compareToBuilder.comparison == 0; ++i) {
Field f = fields[i];
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
try {
compareToBuilder.append(f.get(lhs), f.get(rhs));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
if ( !Modifier.isStatic(f.getModifiers())) {
try {
compareToBuilder.append(f.get(lhs), f.get(rhs));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
}

View File

@ -102,7 +102,7 @@ import java.lang.reflect.Modifier;
*
* @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</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 {
/**
@ -129,11 +129,12 @@ public class EqualsBuilder {
* 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 tested, as they are likely derived
* fields, and not part of the value of the object.
* Transient members will be not be tested, as they are likely derived
* fields, and not part of the value of the object.
* Static fields will not be tested.
*
* @param lhs - Left Hand Side
* @param rhs - Right Hand Side
* @param lhs Left Hand Side
* @param rhs Right Hand Side
* @return boolean - if the two objects have tested equals.
*/
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
* 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.
*
* @param lhs - Left Hand Side
* @param rhs - Right Hand Side
* @param testTransients - whether to include transient fields
* @param lhs Left Hand Side
* @param rhs Right Hand Side
* @param testTransients whether to include transient fields
* @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) {
return true;
}
@ -173,12 +176,14 @@ public class EqualsBuilder {
for (int i = 0; i < fields.length && equalsBuilder.isEquals; ++i) {
Field f = fields[i];
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
try {
equalsBuilder.append(f.get(lhs), f.get(rhs));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
if (!Modifier.isStatic(f.getModifiers())) {
try {
equalsBuilder.append(f.get(lhs), f.get(rhs));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
}

View File

@ -102,7 +102,7 @@ import java.lang.reflect.Modifier;
* </code>
*
* @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 {
@ -165,6 +165,7 @@ public class HashCodeBuilder {
* 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.
* This constructor uses two hard coded choices for the constants needed
* to build a hash code.
*
@ -176,33 +177,6 @@ public class HashCodeBuilder {
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.
* <p>
@ -213,6 +187,7 @@ public class HashCodeBuilder {
* 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.
* This constructor uses two hard coded choices for the constants needed
* to build a hash code.
*
@ -225,6 +200,34 @@ public class HashCodeBuilder {
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.
* <p>
@ -235,6 +238,7 @@ public class HashCodeBuilder {
* 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.
* <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.
@ -261,12 +265,14 @@ public class HashCodeBuilder {
for (int i = 0; i < fields.length; ++i) {
Field f = fields[i];
if (testTransients || !Modifier.isTransient(f.getModifiers())) {
try {
hashCodeBuilder.append(f.get(object));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
if (!Modifier.isStatic(f.getModifiers())) {
try {
hashCodeBuilder.append(f.get(object));
} catch (IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
}