Hi.
Le mer. 12 juil. 2023 à 14:44, <[email protected]> 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 <[email protected]>
> 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: [email protected]
For additional commands, e-mail: [email protected]