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
The following commit(s) were added to refs/heads/master by this push:
new 1418a770b [LANG-1452] RecursiveToStringStyle and
MultilineRecursiveToStringStyle shouldn't recurse into a java.math.BigDecimal
(#1584)
1418a770b is described below
commit 1418a770ba436d15693c3bb29a67e501c2008274
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Jan 25 08:41:44 2026 -0500
[LANG-1452] RecursiveToStringStyle and MultilineRecursiveToStringStyle
shouldn't recurse into a java.math.BigDecimal (#1584)
* Add testLang1641()
* Rename some test methods
* [LANG-1452] RecursiveToStringStyle and MultilineRecursiveToStringStyle
shouldn't recurse into a java.math.BigDecimal
- We already don't recurse into a Decimal and other boxed primitive.
- Don't recurse into Number subclasses.
- Don't recurse into AtomicBoolean.
---
.../lang3/builder/RecursiveToStringStyle.java | 34 ++++++++-----
.../lang3/builder/RecursiveToStringStyleTest.java | 55 +++++++++++++++++++++-
2 files changed, 77 insertions(+), 12 deletions(-)
diff --git
a/src/main/java/org/apache/commons/lang3/builder/RecursiveToStringStyle.java
b/src/main/java/org/apache/commons/lang3/builder/RecursiveToStringStyle.java
index 15968eb12..95695079a 100644
--- a/src/main/java/org/apache/commons/lang3/builder/RecursiveToStringStyle.java
+++ b/src/main/java/org/apache/commons/lang3/builder/RecursiveToStringStyle.java
@@ -17,8 +17,10 @@
package org.apache.commons.lang3.builder;
import java.util.Collection;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.mutable.MutableBoolean;
/**
* Works with {@link ToStringBuilder} to create a "deep" {@code toString}.
@@ -66,16 +68,29 @@ public RecursiveToStringStyle() {
}
/**
- * Returns whether or not to recursively format the given {@link Class}.
- * By default, this method always returns {@code true}, but may be
overwritten by
- * subclasses to filter specific classes.
+ * Tests whether or not to recursively format the given {@link Class}.
+ * <p>
+ * By default, this method always filters out the following:
+ * </p>
+ * <ul>
+ * <li><a
href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.7">Boxed
primitives</a>, see {@link ClassUtils#isPrimitiveWrapper(Class)}
+ * <li>{@link String}</li>
+ * <li>{@link Number} subclasses</li>
+ * <li>{@link AtomicBoolean}</li>
+ * <li>{@link MutableBoolean}</li>
+ * </ul>
*
- * @param clazz
- * The class to test.
- * @return Whether or not to recursively format the given {@link Class}.
+ * @param clazz The class to test.
+ * @return Whether or not to recursively format instances of the given
{@link Class}.
*/
protected boolean accept(final Class<?> clazz) {
- return true;
+ // @formatter:off
+ return !ClassUtils.isPrimitiveWrapper(clazz) &&
+ !String.class.equals(clazz) &&
+ !Number.class.isAssignableFrom(clazz) &&
+ !AtomicBoolean.class.equals(clazz) &&
+ !MutableBoolean.class.equals(clazz);
+ // @formatter:on
}
@Override
@@ -87,10 +102,7 @@ protected void appendDetail(final StringBuffer buffer,
final String fieldName, f
@Override
public void appendDetail(final StringBuffer buffer, final String
fieldName, final Object value) {
- final Class<? extends Object> clazz = value.getClass();
- if (!ClassUtils.isPrimitiveWrapper(clazz) &&
- !String.class.equals(clazz) &&
- accept(clazz)) {
+ if (value != null && accept(value.getClass())) {
buffer.append(ReflectionToStringBuilder.toString(value, this));
} else {
super.appendDetail(buffer, fieldName, value);
diff --git
a/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
b/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
index 2f73484fa..e8618e84d 100644
---
a/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
+++
b/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
@@ -18,10 +18,22 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.lang3.AbstractLangTest;
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.apache.commons.lang3.mutable.MutableByte;
+import org.apache.commons.lang3.mutable.MutableDouble;
+import org.apache.commons.lang3.mutable.MutableFloat;
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.commons.lang3.mutable.MutableLong;
+import org.apache.commons.lang3.mutable.MutableShort;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -85,6 +97,30 @@ void testAppendSuper() {
assertEquals(baseStr + "[a=hello]", new
ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
+ @Test
+ void testAtomicsArray() {
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new AtomicLong[] { new AtomicLong(3), new AtomicLong(6) } }).toString());
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new AtomicInteger[] { new AtomicInteger(3), new AtomicInteger(6) }
}).toString());
+ assertEquals(baseStr + "[{<null>,5,{true,false}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new AtomicBoolean[] { new AtomicBoolean(true), new AtomicBoolean(false) }
}).toString());
+ }
+
+ @Test
+ void testBigDecimal() {
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new BigDecimal[] { BigDecimal.valueOf(3), BigDecimal.valueOf(6) }
}).toString());
+ assertEquals(baseStr + "[{<null>,5,{3.0,6.0}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new BigDecimal[] { BigDecimal.valueOf(3.0), BigDecimal.valueOf(6.0) }
}).toString());
+ }
+
+ @Test
+ void testBigInteger() {
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new BigInteger[] { BigInteger.valueOf(3), BigInteger.valueOf(6) }
}).toString());
+ }
+
@Test
void testBlank() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).toString());
@@ -117,6 +153,24 @@ void testLongArrayArray() {
assertEquals(baseStr + "[<null>]", new
ToStringBuilder(base).append((Object) array).toString());
}
+ @Test
+ void testMutableWrapperArray() {
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableLong[] { new MutableLong(3), new MutableLong(6) } }).toString());
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableInt[] { new MutableInt(3), new MutableInt(6) } }).toString());
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableShort[] { new MutableShort(3), new MutableShort(6) } }).toString());
+ assertEquals(baseStr + "[{<null>,5,{3,6}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableByte[] { new MutableByte((byte) 3), new MutableByte((byte) 6) }
}).toString());
+ assertEquals(baseStr + "[{<null>,5,{3.0,6.0}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableFloat[] { new MutableFloat(3f), new MutableFloat(6f) }
}).toString());
+ assertEquals(baseStr + "[{<null>,5,{3.0,6.0}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableDouble[] { new MutableDouble(3d), new MutableDouble(6d) }
}).toString());
+ assertEquals(baseStr + "[{<null>,5,{true,false}}]",
+ new ToStringBuilder(base).append(new Object[] { null, base,
new MutableBoolean[] { new MutableBoolean(true), new MutableBoolean(false) }
}).toString());
+ }
+
@Test
void testObject() {
final Integer i3 = Integer.valueOf(3);
@@ -174,5 +228,4 @@ void testPrimitiveWrapperArray() {
assertEquals(baseStr + "[{<null>,5,{true,false}}]",
new ToStringBuilder(base).append(new Object[] { null, base,
new Boolean[] { true, false } }).toString());
}
-
}