This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git

commit 2e3feda04337baa483bc26b66f238161dc6c97ac
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Wed Jul 12 08:44:38 2023 -0400

    Throw IllegalArgumentException instead of InternalError in the builder
    package
---
 src/changes/changes.xml                            |   1 +
 .../commons/lang3/builder/CompareToBuilder.java    | 752 ++++++++++-----------
 .../commons/lang3/builder/EqualsBuilder.java       |  20 +-
 .../commons/lang3/builder/HashCodeBuilder.java     |   9 +-
 .../apache/commons/lang3/builder/Reflection.java   |  44 ++
 .../lang3/builder/ReflectionDiffBuilder.java       |   7 +-
 .../lang3/builder/ReflectionToStringBuilder.java   |  14 +-
 7 files changed, 434 insertions(+), 413 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 26d7be48c..da3522029 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -123,6 +123,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="fix" dev="ggregory" due-to="Dimitrios 
Efthymiou">Update Javadoc for the insert methods in ArrayUtils #1078.</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Deprecate ExceptionUtils.ExceptionUtils().</action>
     <action issue="LANG-1697" type="fix" dev="ggregory" due-to="Jan Arne 
Sparka, Gary Gregory">TypeUtils.getRawType() throws a NullPointerException on 
Wildcard GenericArrayType.</action>
+    <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Throw IllegalArgumentException instead of InternalError in the builder 
package.</action>    
     <!-- ADD -->
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add GitHub coverage.yml.</action>
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add EnumUtils.getEnumSystemProperty(...).</action>
diff --git 
a/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java 
b/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java
index 38c69e613..3d411bb15 100644
--- a/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java
@@ -97,19 +97,37 @@ import org.apache.commons.lang3.ObjectUtils;
 public class CompareToBuilder implements Builder<Integer> {
 
     /**
-     * Current state of the comparison as appended fields are checked.
-     */
-    private int comparison;
-
-    /**
-     * Constructor for CompareToBuilder.
+     * Appends to {@code builder} the comparison of {@code lhs}
+     * to {@code rhs} using the fields defined in {@code clazz}.
      *
-     * <p>Starts off assuming that the objects are equal. Multiple calls are
-     * then made to the various append methods, followed by a call to
-     * {@link #toComparison} to get the result.</p>
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
+     * @param clazz  {@link Class} that defines fields to be compared
+     * @param builder  {@link CompareToBuilder} to append to
+     * @param useTransients  whether to compare transient fields
+     * @param excludeFields  fields to exclude
      */
-    public CompareToBuilder() {
-        comparison = 0;
+    private static void reflectionAppend(
+        final Object lhs,
+        final Object rhs,
+        final Class<?> clazz,
+        final CompareToBuilder builder,
+        final boolean useTransients,
+        final String[] excludeFields) {
+
+        final Field[] fields = clazz.getDeclaredFields();
+        AccessibleObject.setAccessible(fields, true);
+        for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
+            final Field field = fields[i];
+            if (!ArrayUtils.contains(excludeFields, field.getName())
+                && !field.getName().contains("$")
+                && (useTransients || 
!Modifier.isTransient(field.getModifiers()))
+                && !Modifier.isStatic(field.getModifiers())) {
+                // IllegalAccessException can't happen. Would get a Security 
exception instead.
+                // Throw a runtime exception in case the impossible happens.
+                builder.append(Reflection.getUnchecked(field, lhs), 
Reflection.getUnchecked(field, rhs));
+            }
+        }
     }
 
     /**
@@ -183,10 +201,11 @@ public class CompareToBuilder implements Builder<Integer> 
{
      *
      * <ul>
      * <li>Static fields will not be compared</li>
-     * <li>If {@code compareTransients} is {@code true},
+     * <li>If the {@code compareTransients} is {@code true},
      *     compares transient members.  Otherwise ignores them, as they
      *     are likely derived fields.</li>
-     * <li>Superclass fields will be compared</li>
+     * <li>Compares superclass fields up to and including {@code 
reflectUpToClass}.
+     *     If {@code reflectUpToClass} is {@code null}, compares all 
superclass fields.</li>
      * </ul>
      *
      * <p>If both {@code lhs} and {@code rhs} are {@code null},
@@ -194,17 +213,41 @@ public class CompareToBuilder implements Builder<Integer> 
{
      *
      * @param lhs  left-hand object
      * @param rhs  right-hand object
-     * @param excludeFields  Collection of String fields to exclude
+     * @param compareTransients  whether to compare transient fields
+     * @param reflectUpToClass  last superclass for which fields are compared
+     * @param excludeFields  fields to exclude
      * @return a negative integer, zero, or a positive integer as {@code lhs}
      *  is less than, equal to, or greater than {@code rhs}
      * @throws NullPointerException  if either {@code lhs} or {@code rhs}
      *  (but not both) is {@code null}
      * @throws ClassCastException  if {@code rhs} is not assignment-compatible
      *  with {@code lhs}
-     * @since 2.2
+     * @since 2.2 (2.0 as {@code reflectionCompare(Object, Object, boolean, 
Class)})
      */
-    public static int reflectionCompare(final Object lhs, final Object rhs, 
final Collection<String> excludeFields) {
-        return reflectionCompare(lhs, rhs, 
ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
+    public static int reflectionCompare(
+        final Object lhs,
+        final Object rhs,
+        final boolean compareTransients,
+        final Class<?> reflectUpToClass,
+        final String... excludeFields) {
+
+        if (lhs == rhs) {
+            return 0;
+        }
+        Objects.requireNonNull(lhs, "lhs");
+        Objects.requireNonNull(rhs, "rhs");
+
+        Class<?> lhsClazz = lhs.getClass();
+        if (!lhsClazz.isInstance(rhs)) {
+            throw new ClassCastException();
+        }
+        final CompareToBuilder compareToBuilder = new CompareToBuilder();
+        reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, 
compareTransients, excludeFields);
+        while (lhsClazz.getSuperclass() != null && lhsClazz != 
reflectUpToClass) {
+            lhsClazz = lhsClazz.getSuperclass();
+            reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, 
compareTransients, excludeFields);
+        }
+        return compareToBuilder.toComparison();
     }
 
     /**
@@ -227,7 +270,7 @@ public class CompareToBuilder implements Builder<Integer> {
      *
      * @param lhs  left-hand object
      * @param rhs  right-hand object
-     * @param excludeFields  array of fields to exclude
+     * @param excludeFields  Collection of String fields to exclude
      * @return a negative integer, zero, or a positive integer as {@code lhs}
      *  is less than, equal to, or greater than {@code rhs}
      * @throws NullPointerException  if either {@code lhs} or {@code rhs}
@@ -236,8 +279,8 @@ public class CompareToBuilder implements Builder<Integer> {
      *  with {@code lhs}
      * @since 2.2
      */
-    public static int reflectionCompare(final Object lhs, final Object rhs, 
final String... excludeFields) {
-        return reflectionCompare(lhs, rhs, false, null, excludeFields);
+    public static int reflectionCompare(final Object lhs, final Object rhs, 
final Collection<String> excludeFields) {
+        return reflectionCompare(lhs, rhs, 
ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
     }
 
     /**
@@ -249,11 +292,10 @@ public class CompareToBuilder implements Builder<Integer> 
{
      *
      * <ul>
      * <li>Static fields will not be compared</li>
-     * <li>If the {@code compareTransients} is {@code true},
+     * <li>If {@code compareTransients} is {@code true},
      *     compares transient members.  Otherwise ignores them, as they
      *     are likely derived fields.</li>
-     * <li>Compares superclass fields up to and including {@code 
reflectUpToClass}.
-     *     If {@code reflectUpToClass} is {@code null}, compares all 
superclass fields.</li>
+     * <li>Superclass fields will be compared</li>
      * </ul>
      *
      * <p>If both {@code lhs} and {@code rhs} are {@code null},
@@ -261,146 +303,74 @@ public class CompareToBuilder implements 
Builder<Integer> {
      *
      * @param lhs  left-hand object
      * @param rhs  right-hand object
-     * @param compareTransients  whether to compare transient fields
-     * @param reflectUpToClass  last superclass for which fields are compared
-     * @param excludeFields  fields to exclude
+     * @param excludeFields  array of fields to exclude
      * @return a negative integer, zero, or a positive integer as {@code lhs}
      *  is less than, equal to, or greater than {@code rhs}
      * @throws NullPointerException  if either {@code lhs} or {@code rhs}
      *  (but not both) is {@code null}
      * @throws ClassCastException  if {@code rhs} is not assignment-compatible
      *  with {@code lhs}
-     * @since 2.2 (2.0 as {@code reflectionCompare(Object, Object, boolean, 
Class)})
+     * @since 2.2
      */
-    public static int reflectionCompare(
-        final Object lhs,
-        final Object rhs,
-        final boolean compareTransients,
-        final Class<?> reflectUpToClass,
-        final String... excludeFields) {
-
-        if (lhs == rhs) {
-            return 0;
-        }
-        Objects.requireNonNull(lhs, "lhs");
-        Objects.requireNonNull(rhs, "rhs");
-
-        Class<?> lhsClazz = lhs.getClass();
-        if (!lhsClazz.isInstance(rhs)) {
-            throw new ClassCastException();
-        }
-        final CompareToBuilder compareToBuilder = new CompareToBuilder();
-        reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, 
compareTransients, excludeFields);
-        while (lhsClazz.getSuperclass() != null && lhsClazz != 
reflectUpToClass) {
-            lhsClazz = lhsClazz.getSuperclass();
-            reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, 
compareTransients, excludeFields);
-        }
-        return compareToBuilder.toComparison();
+    public static int reflectionCompare(final Object lhs, final Object rhs, 
final String... excludeFields) {
+        return reflectionCompare(lhs, rhs, false, null, excludeFields);
     }
 
     /**
-     * Appends to {@code builder} the comparison of {@code lhs}
-     * to {@code rhs} using the fields defined in {@code clazz}.
-     *
-     * @param lhs  left-hand object
-     * @param rhs  right-hand object
-     * @param clazz  {@link Class} that defines fields to be compared
-     * @param builder  {@link CompareToBuilder} to append to
-     * @param useTransients  whether to compare transient fields
-     * @param excludeFields  fields to exclude
+     * Current state of the comparison as appended fields are checked.
      */
-    private static void reflectionAppend(
-        final Object lhs,
-        final Object rhs,
-        final Class<?> clazz,
-        final CompareToBuilder builder,
-        final boolean useTransients,
-        final String[] excludeFields) {
-
-        final Field[] fields = clazz.getDeclaredFields();
-        AccessibleObject.setAccessible(fields, true);
-        for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
-            final Field field = fields[i];
-            if (!ArrayUtils.contains(excludeFields, field.getName())
-                && !field.getName().contains("$")
-                && (useTransients || 
!Modifier.isTransient(field.getModifiers()))
-                && !Modifier.isStatic(field.getModifiers())) {
-                try {
-                    builder.append(field.get(lhs), field.get(rhs));
-                } catch (final 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");
-                }
-            }
-        }
-    }
+    private int comparison;
 
     /**
-     * Appends to the {@code builder} the {@code compareTo(Object)}
-     * result of the superclass.
+     * Constructor for CompareToBuilder.
      *
-     * @param superCompareTo  result of calling {@code super.compareTo(Object)}
-     * @return this
-     * @since 2.0
+     * <p>Starts off assuming that the objects are equal. Multiple calls are
+     * then made to the various append methods, followed by a call to
+     * {@link #toComparison} to get the result.</p>
      */
-    public CompareToBuilder appendSuper(final int superCompareTo) {
-        if (comparison != 0) {
-            return this;
-        }
-        comparison = superCompareTo;
-        return this;
+    public CompareToBuilder() {
+        comparison = 0;
     }
 
     /**
      * Appends to the {@code builder} the comparison of
-     * two {@link Object}s.
-     *
-     * <ol>
-     * <li>Check if {@code lhs == rhs}</li>
-     * <li>Check if either {@code lhs} or {@code rhs} is {@code null},
-     *     a {@code null} object is less than a non-{@code null} object</li>
-     * <li>Check the object contents</li>
-     * </ol>
-     *
-     * <p>{@code lhs} must either be an array or implement {@link 
Comparable}.</p>
+     * two {@code booleans}s.
      *
-     * @param lhs  left-hand object
-     * @param rhs  right-hand object
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
      * @return this
-     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
-     *  with {@code lhs}
-     */
-    public CompareToBuilder append(final Object lhs, final Object rhs) {
-        return append(lhs, rhs, null);
+      */
+    public CompareToBuilder append(final boolean lhs, final boolean rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs) {
+            comparison = 1;
+        } else {
+            comparison = -1;
+        }
+        return this;
     }
 
     /**
-     * Appends to the {@code builder} the comparison of
-     * two {@link Object}s.
+     * Appends to the {@code builder} the deep comparison of
+     * two {@code boolean} arrays.
      *
      * <ol>
-     * <li>Check if {@code lhs == rhs}</li>
-     * <li>Check if either {@code lhs} or {@code rhs} is {@code null},
-     *     a {@code null} object is less than a non-{@code null} object</li>
-     * <li>Check the object contents</li>
+     *  <li>Check if arrays are the same using {@code ==}</li>
+     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(boolean, boolean)}</li>
      * </ol>
      *
-     * <p>If {@code lhs} is an array, array comparison methods will be used.
-     * Otherwise {@code comparator} will be used to compare the objects.
-     * If {@code comparator} is {@code null}, {@code lhs} must
-     * implement {@link Comparable} instead.</p>
-     *
-     * @param lhs  left-hand object
-     * @param rhs  right-hand object
-     * @param comparator  {@link Comparator} used to compare the objects,
-     *  {@code null} means treat lhs as {@link Comparable}
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
      * @return this
-     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
-     *  with {@code lhs}
-     * @since 2.0
      */
-    public CompareToBuilder append(final Object lhs, final Object rhs, final 
Comparator<?> comparator) {
+    public CompareToBuilder append(final boolean[] lhs, final boolean[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -415,94 +385,69 @@ public class CompareToBuilder implements Builder<Integer> 
{
             comparison = 1;
             return this;
         }
-        if (ObjectUtils.isArray(lhs)) {
-            // factor out array case in order to keep method small enough to 
be inlined
-            appendArray(lhs, rhs, comparator);
-        } else // the simple case, not an array, just test the element
-        if (comparator == null) {
-            @SuppressWarnings("unchecked") // assume this can be done; if not 
throw CCE as per Javadoc
-            final Comparable<Object> comparable = (Comparable<Object>) lhs;
-            comparison = comparable.compareTo(rhs);
-        } else {
-            @SuppressWarnings("unchecked") // assume this can be done; if not 
throw CCE as per Javadoc
-            final Comparator<Object> comparator2 = (Comparator<Object>) 
comparator;
-            comparison = comparator2.compare(lhs, rhs);
+        if (lhs.length != rhs.length) {
+            comparison = lhs.length < rhs.length ? -1 : 1;
+            return this;
         }
-        return this;
-    }
-
-    private void appendArray(final Object lhs, final Object rhs, final 
Comparator<?> comparator) {
-        // switch on type of array, to dispatch to the correct handler
-        // handles multidimensional arrays
-        // throws a ClassCastException if rhs is not the correct array type
-        if (lhs instanceof long[]) {
-            append((long[]) lhs, (long[]) rhs);
-        } else if (lhs instanceof int[]) {
-            append((int[]) lhs, (int[]) rhs);
-        } else if (lhs instanceof short[]) {
-            append((short[]) lhs, (short[]) rhs);
-        } else if (lhs instanceof char[]) {
-            append((char[]) lhs, (char[]) rhs);
-        } else if (lhs instanceof byte[]) {
-            append((byte[]) lhs, (byte[]) rhs);
-        } else if (lhs instanceof double[]) {
-            append((double[]) lhs, (double[]) rhs);
-        } else if (lhs instanceof float[]) {
-            append((float[]) lhs, (float[]) rhs);
-        } else if (lhs instanceof boolean[]) {
-            append((boolean[]) lhs, (boolean[]) rhs);
-        } else {
-            // not an array of primitives
-            // throws a ClassCastException if rhs is not an array
-            append((Object[]) lhs, (Object[]) rhs, comparator);
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
         }
+        return this;
     }
 
     /**
      * Appends to the {@code builder} the comparison of
-     * two {@code long}s.
+     * two {@code byte}s.
      *
      * @param lhs  left-hand value
      * @param rhs  right-hand value
      * @return this
      */
-    public CompareToBuilder append(final long lhs, final long rhs) {
+    public CompareToBuilder append(final byte lhs, final byte rhs) {
         if (comparison != 0) {
             return this;
         }
-        comparison = Long.compare(lhs, rhs);
+        comparison = Byte.compare(lhs, rhs);
         return this;
     }
 
     /**
-     * Appends to the {@code builder} the comparison of
-     * two {@code int}s.
+     * Appends to the {@code builder} the deep comparison of
+     * two {@code byte} arrays.
      *
-     * @param lhs  left-hand value
-     * @param rhs  right-hand value
+     * <ol>
+     *  <li>Check if arrays are the same using {@code ==}</li>
+     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(byte, 
byte)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final int lhs, final int rhs) {
+    public CompareToBuilder append(final byte[] lhs, final byte[] rhs) {
         if (comparison != 0) {
             return this;
         }
-        comparison = Integer.compare(lhs, rhs);
-        return this;
-    }
-
-    /**
-     * Appends to the {@code builder} the comparison of
-     * two {@code short}s.
-     *
-     * @param lhs  left-hand value
-     * @param rhs  right-hand value
-     * @return this
-     */
-    public CompareToBuilder append(final short lhs, final short rhs) {
-        if (comparison != 0) {
+        if (lhs == rhs) {
             return this;
         }
-        comparison = Short.compare(lhs, rhs);
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = 1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = lhs.length < rhs.length ? -1 : 1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
         return this;
     }
 
@@ -523,18 +468,42 @@ public class CompareToBuilder implements Builder<Integer> 
{
     }
 
     /**
-     * Appends to the {@code builder} the comparison of
-     * two {@code byte}s.
+     * Appends to the {@code builder} the deep comparison of
+     * two {@code char} arrays.
      *
-     * @param lhs  left-hand value
-     * @param rhs  right-hand value
+     * <ol>
+     *  <li>Check if arrays are the same using {@code ==}</li>
+     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(char, 
char)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final byte lhs, final byte rhs) {
+    public CompareToBuilder append(final char[] lhs, final char[] rhs) {
         if (comparison != 0) {
             return this;
         }
-        comparison = Byte.compare(lhs, rhs);
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = 1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = lhs.length < rhs.length ? -1 : 1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
         return this;
     }
 
@@ -559,98 +528,22 @@ public class CompareToBuilder implements Builder<Integer> 
{
         return this;
     }
 
-    /**
-     * Appends to the {@code builder} the comparison of
-     * two {@code float}s.
-     *
-     * <p>This handles NaNs, Infinities, and {@code -0.0}.</p>
-     *
-     * <p>It is compatible with the hash code generated by
-     * {@link HashCodeBuilder}.</p>
-     *
-     * @param lhs  left-hand value
-     * @param rhs  right-hand value
-     * @return this
-     */
-    public CompareToBuilder append(final float lhs, final float rhs) {
-        if (comparison != 0) {
-            return this;
-        }
-        comparison = Float.compare(lhs, rhs);
-        return this;
-    }
-
-    /**
-     * Appends to the {@code builder} the comparison of
-     * two {@code booleans}s.
-     *
-     * @param lhs  left-hand value
-     * @param rhs  right-hand value
-     * @return this
-      */
-    public CompareToBuilder append(final boolean lhs, final boolean rhs) {
-        if (comparison != 0) {
-            return this;
-        }
-        if (lhs == rhs) {
-            return this;
-        }
-        if (lhs) {
-            comparison = 1;
-        } else {
-            comparison = -1;
-        }
-        return this;
-    }
-
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@link Object} arrays.
-     *
-     * <ol>
-     *  <li>Check if arrays are the same using {@code ==}</li>
-     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a short length array is less than a long 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
-     * </ol>
-     *
-     * <p>This method will also will be called for the top level of 
multi-dimensional,
-     * ragged, and multi-typed arrays.</p>
-     *
-     * @param lhs  left-hand array
-     * @param rhs  right-hand array
-     * @return this
-     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
-     *  with {@code lhs}
-     */
-    public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
-        return append(lhs, rhs, null);
-    }
-
-    /**
-     * Appends to the {@code builder} the deep comparison of
-     * two {@link Object} arrays.
+     * two {@code double} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a short length array is less than a long 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(double, double)}</li>
      * </ol>
      *
-     * <p>This method will also will be called for the top level of 
multi-dimensional,
-     * ragged, and multi-typed arrays.</p>
-     *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
-     * @param comparator  {@link Comparator} to use to compare the array 
elements,
-     *  {@code null} means to treat {@code lhs} elements as {@link Comparable}.
      * @return this
-     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
-     *  with {@code lhs}
-     * @since 2.0
      */
-    public CompareToBuilder append(final Object[] lhs, final Object[] rhs, 
final Comparator<?> comparator) {
+    public CompareToBuilder append(final double[] lhs, final double[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -670,67 +563,48 @@ public class CompareToBuilder implements Builder<Integer> 
{
             return this;
         }
         for (int i = 0; i < lhs.length && comparison == 0; i++) {
-            append(lhs[i], rhs[i], comparator);
+            append(lhs[i], rhs[i]);
         }
         return this;
     }
 
     /**
-     * Appends to the {@code builder} the deep comparison of
-     * two {@code long} arrays.
+     * Appends to the {@code builder} the comparison of
+     * two {@code float}s.
      *
-     * <ol>
-     *  <li>Check if arrays are the same using {@code ==}</li>
-     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link #append(long, 
long)}</li>
-     * </ol>
+     * <p>This handles NaNs, Infinities, and {@code -0.0}.</p>
      *
-     * @param lhs  left-hand array
-     * @param rhs  right-hand array
+     * <p>It is compatible with the hash code generated by
+     * {@link HashCodeBuilder}.</p>
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
      * @return this
      */
-    public CompareToBuilder append(final long[] lhs, final long[] rhs) {
+    public CompareToBuilder append(final float lhs, final float rhs) {
         if (comparison != 0) {
-            return this;
-        }
-        if (lhs == rhs) {
-            return this;
-        }
-        if (lhs == null) {
-            comparison = -1;
-            return this;
-        }
-        if (rhs == null) {
-            comparison = 1;
-            return this;
-        }
-        if (lhs.length != rhs.length) {
-            comparison = lhs.length < rhs.length ? -1 : 1;
-            return this;
-        }
-        for (int i = 0; i < lhs.length && comparison == 0; i++) {
-            append(lhs[i], rhs[i]);
+            return this;
         }
+        comparison = Float.compare(lhs, rhs);
         return this;
     }
 
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code int} arrays.
+     * two {@code float} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
      *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link #append(int, 
int)}</li>
+     *  <li>Check array contents element by element using {@link 
#append(float, float)}</li>
      * </ol>
      *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final int[] lhs, final int[] rhs) {
+    public CompareToBuilder append(final float[] lhs, final float[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -755,22 +629,38 @@ public class CompareToBuilder implements Builder<Integer> 
{
         return this;
     }
 
+    /**
+     * Appends to the {@code builder} the comparison of
+     * two {@code int}s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this
+     */
+    public CompareToBuilder append(final int lhs, final int rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Integer.compare(lhs, rhs);
+        return this;
+    }
+
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code short} arrays.
+     * two {@code int} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
      *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(short, short)}</li>
+     *  <li>Check array contents element by element using {@link #append(int, 
int)}</li>
      * </ol>
      *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final short[] lhs, final short[] rhs) {
+    public CompareToBuilder append(final int[] lhs, final int[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -795,22 +685,38 @@ public class CompareToBuilder implements Builder<Integer> 
{
         return this;
     }
 
+    /**
+     * Appends to the {@code builder} the comparison of
+     * two {@code long}s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this
+     */
+    public CompareToBuilder append(final long lhs, final long rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Long.compare(lhs, rhs);
+        return this;
+    }
+
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code char} arrays.
+     * two {@code long} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
      *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link #append(char, 
char)}</li>
+     *  <li>Check array contents element by element using {@link #append(long, 
long)}</li>
      * </ol>
      *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final char[] lhs, final char[] rhs) {
+    public CompareToBuilder append(final long[] lhs, final long[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -836,21 +742,54 @@ public class CompareToBuilder implements Builder<Integer> 
{
     }
 
     /**
-     * Appends to the {@code builder} the deep comparison of
-     * two {@code byte} arrays.
+     * Appends to the {@code builder} the comparison of
+     * two {@link Object}s.
      *
      * <ol>
-     *  <li>Check if arrays are the same using {@code ==}</li>
-     *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link #append(byte, 
byte)}</li>
+     * <li>Check if {@code lhs == rhs}</li>
+     * <li>Check if either {@code lhs} or {@code rhs} is {@code null},
+     *     a {@code null} object is less than a non-{@code null} object</li>
+     * <li>Check the object contents</li>
      * </ol>
      *
-     * @param lhs  left-hand array
-     * @param rhs  right-hand array
+     * <p>{@code lhs} must either be an array or implement {@link 
Comparable}.</p>
+     *
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
      * @return this
+     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
+     *  with {@code lhs}
      */
-    public CompareToBuilder append(final byte[] lhs, final byte[] rhs) {
+    public CompareToBuilder append(final Object lhs, final Object rhs) {
+        return append(lhs, rhs, null);
+    }
+
+    /**
+     * Appends to the {@code builder} the comparison of
+     * two {@link Object}s.
+     *
+     * <ol>
+     * <li>Check if {@code lhs == rhs}</li>
+     * <li>Check if either {@code lhs} or {@code rhs} is {@code null},
+     *     a {@code null} object is less than a non-{@code null} object</li>
+     * <li>Check the object contents</li>
+     * </ol>
+     *
+     * <p>If {@code lhs} is an array, array comparison methods will be used.
+     * Otherwise {@code comparator} will be used to compare the objects.
+     * If {@code comparator} is {@code null}, {@code lhs} must
+     * implement {@link Comparable} instead.</p>
+     *
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
+     * @param comparator  {@link Comparator} used to compare the objects,
+     *  {@code null} means treat lhs as {@link Comparable}
+     * @return this
+     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
+     *  with {@code lhs}
+     * @since 2.0
+     */
+    public CompareToBuilder append(final Object lhs, final Object rhs, final 
Comparator<?> comparator) {
         if (comparison != 0) {
             return this;
         }
@@ -865,72 +804,70 @@ public class CompareToBuilder implements Builder<Integer> 
{
             comparison = 1;
             return this;
         }
-        if (lhs.length != rhs.length) {
-            comparison = lhs.length < rhs.length ? -1 : 1;
-            return this;
-        }
-        for (int i = 0; i < lhs.length && comparison == 0; i++) {
-            append(lhs[i], rhs[i]);
+        if (ObjectUtils.isArray(lhs)) {
+            // factor out array case in order to keep method small enough to 
be inlined
+            appendArray(lhs, rhs, comparator);
+        } else // the simple case, not an array, just test the element
+        if (comparator == null) {
+            @SuppressWarnings("unchecked") // assume this can be done; if not 
throw CCE as per Javadoc
+            final Comparable<Object> comparable = (Comparable<Object>) lhs;
+            comparison = comparable.compareTo(rhs);
+        } else {
+            @SuppressWarnings("unchecked") // assume this can be done; if not 
throw CCE as per Javadoc
+            final Comparator<Object> comparator2 = (Comparator<Object>) 
comparator;
+            comparison = comparator2.compare(lhs, rhs);
         }
         return this;
     }
 
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code double} arrays.
+     * two {@link Object} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(double, double)}</li>
+     *  <li>Check array length, a short length array is less than a long 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
      * </ol>
      *
+     * <p>This method will also will be called for the top level of 
multi-dimensional,
+     * ragged, and multi-typed arrays.</p>
+     *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
      * @return this
+     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
+     *  with {@code lhs}
      */
-    public CompareToBuilder append(final double[] lhs, final double[] rhs) {
-        if (comparison != 0) {
-            return this;
-        }
-        if (lhs == rhs) {
-            return this;
-        }
-        if (lhs == null) {
-            comparison = -1;
-            return this;
-        }
-        if (rhs == null) {
-            comparison = 1;
-            return this;
-        }
-        if (lhs.length != rhs.length) {
-            comparison = lhs.length < rhs.length ? -1 : 1;
-            return this;
-        }
-        for (int i = 0; i < lhs.length && comparison == 0; i++) {
-            append(lhs[i], rhs[i]);
-        }
-        return this;
+    public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
+        return append(lhs, rhs, null);
     }
 
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code float} arrays.
+     * two {@link Object} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
-     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(float, float)}</li>
+     *  <li>Check array length, a short length array is less than a long 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
      * </ol>
      *
+     * <p>This method will also will be called for the top level of 
multi-dimensional,
+     * ragged, and multi-typed arrays.</p>
+     *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
+     * @param comparator  {@link Comparator} to use to compare the array 
elements,
+     *  {@code null} means to treat {@code lhs} elements as {@link Comparable}.
      * @return this
+     * @throws ClassCastException  if {@code rhs} is not assignment-compatible
+     *  with {@code lhs}
+     * @since 2.0
      */
-    public CompareToBuilder append(final float[] lhs, final float[] rhs) {
+    public CompareToBuilder append(final Object[] lhs, final Object[] rhs, 
final Comparator<?> comparator) {
         if (comparison != 0) {
             return this;
         }
@@ -950,27 +887,43 @@ public class CompareToBuilder implements Builder<Integer> 
{
             return this;
         }
         for (int i = 0; i < lhs.length && comparison == 0; i++) {
-            append(lhs[i], rhs[i]);
+            append(lhs[i], rhs[i], comparator);
+        }
+        return this;
+    }
+
+    /**
+     * Appends to the {@code builder} the comparison of
+     * two {@code short}s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this
+     */
+    public CompareToBuilder append(final short lhs, final short rhs) {
+        if (comparison != 0) {
+            return this;
         }
+        comparison = Short.compare(lhs, rhs);
         return this;
     }
 
     /**
      * Appends to the {@code builder} the deep comparison of
-     * two {@code boolean} arrays.
+     * two {@code short} arrays.
      *
      * <ol>
      *  <li>Check if arrays are the same using {@code ==}</li>
      *  <li>Check if for {@code null}, {@code null} is less than non-{@code 
null}</li>
      *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
-     *  <li>Check array contents element by element using {@link 
#append(boolean, boolean)}</li>
+     *  <li>Check array contents element by element using {@link 
#append(short, short)}</li>
      * </ol>
      *
      * @param lhs  left-hand array
      * @param rhs  right-hand array
      * @return this
      */
-    public CompareToBuilder append(final boolean[] lhs, final boolean[] rhs) {
+    public CompareToBuilder append(final short[] lhs, final short[] rhs) {
         if (comparison != 0) {
             return this;
         }
@@ -995,17 +948,47 @@ public class CompareToBuilder implements Builder<Integer> 
{
         return this;
     }
 
+    private void appendArray(final Object lhs, final Object rhs, final 
Comparator<?> comparator) {
+        // switch on type of array, to dispatch to the correct handler
+        // handles multidimensional arrays
+        // throws a ClassCastException if rhs is not the correct array type
+        if (lhs instanceof long[]) {
+            append((long[]) lhs, (long[]) rhs);
+        } else if (lhs instanceof int[]) {
+            append((int[]) lhs, (int[]) rhs);
+        } else if (lhs instanceof short[]) {
+            append((short[]) lhs, (short[]) rhs);
+        } else if (lhs instanceof char[]) {
+            append((char[]) lhs, (char[]) rhs);
+        } else if (lhs instanceof byte[]) {
+            append((byte[]) lhs, (byte[]) rhs);
+        } else if (lhs instanceof double[]) {
+            append((double[]) lhs, (double[]) rhs);
+        } else if (lhs instanceof float[]) {
+            append((float[]) lhs, (float[]) rhs);
+        } else if (lhs instanceof boolean[]) {
+            append((boolean[]) lhs, (boolean[]) rhs);
+        } else {
+            // not an array of primitives
+            // throws a ClassCastException if rhs is not an array
+            append((Object[]) lhs, (Object[]) rhs, comparator);
+        }
+    }
+
     /**
-     * Returns a negative integer, a positive integer, or zero as
-     * the {@code builder} has judged the "left-hand" side
-     * as less than, greater than, or equal to the "right-hand"
-     * side.
+     * Appends to the {@code builder} the {@code compareTo(Object)}
+     * result of the superclass.
      *
-     * @return final comparison result
-     * @see #build()
+     * @param superCompareTo  result of calling {@code super.compareTo(Object)}
+     * @return this
+     * @since 2.0
      */
-    public int toComparison() {
-        return comparison;
+    public CompareToBuilder appendSuper(final int superCompareTo) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = superCompareTo;
+        return this;
     }
 
     /**
@@ -1022,5 +1005,18 @@ public class CompareToBuilder implements 
Builder<Integer> {
     public Integer build() {
         return Integer.valueOf(toComparison());
     }
+
+    /**
+     * Returns a negative integer, a positive integer, or zero as
+     * the {@code builder} has judged the "left-hand" side
+     * as less than, greater than, or equal to the "right-hand"
+     * side.
+     *
+     * @return final comparison result
+     * @see #build()
+     */
+    public int toComparison() {
+        return comparison;
+    }
 }
 
diff --git a/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java 
b/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java
index 6f843ca9e..b34e9d390 100644
--- a/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java
@@ -561,19 +561,13 @@ public class EqualsBuilder implements Builder<Boolean> {
             final Field[] fields = clazz.getDeclaredFields();
             AccessibleObject.setAccessible(fields, true);
             for (int i = 0; i < fields.length && isEquals; i++) {
-                final Field f = fields[i];
-                if (!ArrayUtils.contains(excludeFields, f.getName())
-                    && !f.getName().contains("$")
-                    && (testTransients || 
!Modifier.isTransient(f.getModifiers()))
-                    && !Modifier.isStatic(f.getModifiers())
-                    && !f.isAnnotationPresent(EqualsExclude.class)) {
-                    try {
-                        append(f.get(lhs), f.get(rhs));
-                    } catch (final 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");
-                    }
+                final Field field = fields[i];
+                if (!ArrayUtils.contains(excludeFields, field.getName())
+                    && !field.getName().contains("$")
+                    && (testTransients || 
!Modifier.isTransient(field.getModifiers()))
+                    && !Modifier.isStatic(field.getModifiers())
+                    && !field.isAnnotationPresent(EqualsExclude.class)) {
+                    append(Reflection.getUnchecked(field, lhs), 
Reflection.getUnchecked(field, rhs));
                 }
             }
         } finally {
diff --git 
a/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java 
b/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java
index 9c86c76f7..afe59a8bd 100644
--- a/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java
@@ -191,14 +191,7 @@ public class HashCodeBuilder implements Builder<Integer> {
                     && (useTransients || 
!Modifier.isTransient(field.getModifiers()))
                     && !Modifier.isStatic(field.getModifiers())
                     && !field.isAnnotationPresent(HashCodeExclude.class)) {
-                    try {
-                        final Object fieldValue = field.get(object);
-                        builder.append(fieldValue);
-                    } catch (final 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");
-                    }
+                    builder.append(Reflection.getUnchecked(field, object));
                 }
             }
         } finally {
diff --git a/src/main/java/org/apache/commons/lang3/builder/Reflection.java 
b/src/main/java/org/apache/commons/lang3/builder/Reflection.java
new file mode 100644
index 000000000..119bfe9b2
--- /dev/null
+++ b/src/main/java/org/apache/commons/lang3/builder/Reflection.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.builder;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+/**
+ * Package-private reflection code.
+ */
+class Reflection {
+
+    /**
+     * Delegates to {@link Field#get(Object)} and rethrows {@link 
IllegalAccessException} as {@link IllegalArgumentException}.
+     *
+     * @param field The receiver of the get call.
+     * @param obj   The argument of the get call.
+     * @return The result of the get call.
+     * @throws IllegalArgumentException Thrown after catching {@link 
IllegalAccessException}.
+     */
+    static Object getUnchecked(final Field field, final Object obj) {
+        try {
+            return Objects.requireNonNull(field, "field").get(obj);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+}
diff --git 
a/src/main/java/org/apache/commons/lang3/builder/ReflectionDiffBuilder.java 
b/src/main/java/org/apache/commons/lang3/builder/ReflectionDiffBuilder.java
index bacc0cb89..a5a8f9496 100644
--- a/src/main/java/org/apache/commons/lang3/builder/ReflectionDiffBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/ReflectionDiffBuilder.java
@@ -151,12 +151,11 @@ public class ReflectionDiffBuilder<T> implements 
Builder<DiffResult<T>> {
         for (final Field field : FieldUtils.getAllFields(clazz)) {
             if (accept(field)) {
                 try {
-                    diffBuilder.append(field.getName(), 
FieldUtils.readField(field, left, true),
-                            FieldUtils.readField(field, right, true));
-                } catch (final IllegalAccessException ex) {
+                    diffBuilder.append(field.getName(), 
FieldUtils.readField(field, left, true), FieldUtils.readField(field, right, 
true));
+                } catch (final 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: " + ex.getMessage());
+                    throw new IllegalArgumentException("Unexpected 
IllegalAccessException: " + e.getMessage(), e);
                 }
             }
         }
diff --git 
a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java 
b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
index 8bb0d0e10..d6413681b 100644
--- 
a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
+++ 
b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
@@ -657,16 +657,10 @@ public class ReflectionToStringBuilder extends 
ToStringBuilder {
         for (final Field field : fields) {
             final String fieldName = field.getName();
             if (this.accept(field)) {
-                try {
-                    // Warning: Field.get(Object) creates wrappers objects for 
primitive types.
-                    final Object fieldValue = this.getValue(field);
-                    if (!excludeNullValues || fieldValue != null) {
-                        this.append(fieldName, fieldValue, 
!field.isAnnotationPresent(ToStringSummary.class));
-                    }
-                } catch (final IllegalAccessException ex) {
-                    // this can't happen. Would get a Security exception 
instead
-                    // throw a runtime exception in case the impossible 
happens.
-                    throw new InternalError("Unexpected 
IllegalAccessException: " + ex.getMessage());
+                // Warning: Field.get(Object) creates wrappers objects for 
primitive types.
+                final Object fieldValue = Reflection.getUnchecked(field, 
getObject());
+                if (!excludeNullValues || fieldValue != null) {
+                    this.append(fieldName, fieldValue, 
!field.isAnnotationPresent(ToStringSummary.class));
                 }
             }
         }

Reply via email to