There must be something messed up with EOLs despite my git autocrlf settings... sorry about that.
Gary On Wed, Jul 12, 2023, 08:51 Gilles Sadowski <gillese...@gmail.com> wrote: > Hi. > > Le mer. 12 juil. 2023 à 14:44, <ggreg...@apache.org> a écrit : > > > > 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 > > The diff below contains a bunch of (formatting ?) changes that > have nothing to do with this commit message. > > Regards, > Gilles > > > --- > > 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)); > > } > > } > > } > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > >