From aea52bdea531f724c47589b2fafce2605161f591 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Tue, 17 Sep 2002 22:06:38 +0000 Subject: [PATCH] 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 --- .../lang/builder/CompareToBuilder.java | 33 +++++---- .../commons/lang/builder/EqualsBuilder.java | 35 +++++---- .../commons/lang/builder/HashCodeBuilder.java | 74 ++++++++++--------- 3 files changed, 79 insertions(+), 63 deletions(-) diff --git a/src/java/org/apache/commons/lang/builder/CompareToBuilder.java b/src/java/org/apache/commons/lang/builder/CompareToBuilder.java index 2bf9a28a7..8e2061f8f 100644 --- a/src/java/org/apache/commons/lang/builder/CompareToBuilder.java +++ b/src/java/org/apache/commons/lang/builder/CompareToBuilder.java @@ -99,7 +99,7 @@ import org.apache.commons.lang.NumberUtils; * * @author Steve Downey * @author Stephen Colebourne - * @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"); + } } } } diff --git a/src/java/org/apache/commons/lang/builder/EqualsBuilder.java b/src/java/org/apache/commons/lang/builder/EqualsBuilder.java index a9d626cb9..19d7a4e5d 100644 --- a/src/java/org/apache/commons/lang/builder/EqualsBuilder.java +++ b/src/java/org/apache/commons/lang/builder/EqualsBuilder.java @@ -102,7 +102,7 @@ import java.lang.reflect.Modifier; * * @author Steve Downey * @author Stephen Colebourne - * @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"); + } } } } diff --git a/src/java/org/apache/commons/lang/builder/HashCodeBuilder.java b/src/java/org/apache/commons/lang/builder/HashCodeBuilder.java index ee5b4003c..f861e9361 100644 --- a/src/java/org/apache/commons/lang/builder/HashCodeBuilder.java +++ b/src/java/org/apache/commons/lang/builder/HashCodeBuilder.java @@ -102,7 +102,7 @@ import java.lang.reflect.Modifier; * * * @author Stephen Colebourne - * @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. - *

- * 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. - *

- * 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. *

@@ -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. + *

+ * 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. + *

+ * 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. *

@@ -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. *

* 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"); + } } } }