Browse Source

Use == instead of instanceof for primitive array type checks

Closes gh-35962
pull/35968/head
Sam Brannen 2 weeks ago
parent
commit
0a86a7e3a8
  1. 80
      spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
  2. 40
      spring-core/src/main/java/org/springframework/util/ObjectUtils.java
  3. 7
      spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java

80
spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java

@ -167,40 +167,41 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i @@ -167,40 +167,41 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
* @return the formatted string representation
*/
private String toString(Object value) {
if (value instanceof String str) {
return '"' + str + '"';
Class<?> type = value.getClass();
if (type.isArray()) {
StringBuilder builder = new StringBuilder("{");
for (int i = 0; i < Array.getLength(value); i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(toString(Array.get(value, i)));
}
builder.append('}');
return builder.toString();
}
if (type == String.class) {
return '"' + ((String) value) + '"';
}
if (value instanceof Character) {
if (type == Character.class) {
return '\'' + value.toString() + '\'';
}
if (value instanceof Byte) {
if (type == Byte.class) {
return String.format("(byte) 0x%02X", value);
}
if (value instanceof Long longValue) {
return Long.toString(longValue) + 'L';
if (type == Long.class) {
return Long.toString((Long) value) + 'L';
}
if (value instanceof Float floatValue) {
return Float.toString(floatValue) + 'f';
if (type == Float.class) {
return Float.toString((Float) value) + 'f';
}
if (value instanceof Double doubleValue) {
return Double.toString(doubleValue) + 'd';
if (type == Double.class) {
return Double.toString((Double) value) + 'd';
}
if (value instanceof Enum<?> e) {
return e.name();
}
if (value instanceof Class<?> clazz) {
return getName(clazz) + ".class";
}
if (value.getClass().isArray()) {
StringBuilder builder = new StringBuilder("{");
for (int i = 0; i < Array.getLength(value); i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(toString(Array.get(value, i)));
}
builder.append('}');
return builder.toString();
if (type == Class.class) {
return getName((Class<?>) value) + ".class";
}
return String.valueOf(value);
}
@ -226,29 +227,30 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i @@ -226,29 +227,30 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
* @param array the array to clone
*/
private Object cloneArray(Object array) {
if (array instanceof boolean[] booleans) {
return booleans.clone();
Class<?> type = array.getClass();
if (type == boolean[].class) {
return ((boolean[]) array).clone();
}
if (array instanceof byte[] bytes) {
return bytes.clone();
if (type == byte[].class) {
return ((byte[]) array).clone();
}
if (array instanceof char[] chars) {
return chars.clone();
if (type == char[].class) {
return ((char[]) array).clone();
}
if (array instanceof double[] doubles) {
return doubles.clone();
if (type == double[].class) {
return ((double[]) array).clone();
}
if (array instanceof float[] floats) {
return floats.clone();
if (type == float[].class) {
return ((float[]) array).clone();
}
if (array instanceof int[] ints) {
return ints.clone();
if (type == int[].class) {
return ((int[]) array).clone();
}
if (array instanceof long[] longs) {
return longs.clone();
if (type == long[].class) {
return ((long[]) array).clone();
}
if (array instanceof short[] shorts) {
return shorts.clone();
if (type == short[].class) {
return ((short[]) array).clone();
}
// else

40
spring-core/src/main/java/org/springframework/util/ObjectUtils.java

@ -354,41 +354,43 @@ public abstract class ObjectUtils { @@ -354,41 +354,43 @@ public abstract class ObjectUtils {
}
/**
* Compare the given arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* Compare the given arrays with {@code Arrays.equals(x, y)} variants, performing
* an equality check based on the array elements rather than the array reference.
* @param o1 first array to compare
* @param o2 second array to compare
* @return whether the given objects are equal
* @see #nullSafeEquals(Object, Object)
* @see java.util.Arrays#equals
* @see java.util.Arrays
*/
private static boolean arrayEquals(Object o1, Object o2) {
if (o1 instanceof Object[] objects1 && o2 instanceof Object[] objects2) {
return Arrays.equals(objects1, objects2);
}
if (o1 instanceof boolean[] booleans1 && o2 instanceof boolean[] booleans2) {
return Arrays.equals(booleans1, booleans2);
Class<?> type1 = o1.getClass();
Class<?> type2 = o2.getClass();
if (type1 == boolean[].class && type2 == boolean[].class) {
return Arrays.equals((boolean[]) o1, (boolean[]) o2);
}
if (o1 instanceof byte[] bytes1 && o2 instanceof byte[] bytes2) {
return Arrays.equals(bytes1, bytes2);
if (type1 == byte[].class && type2 == byte[].class) {
return Arrays.equals((byte[]) o1, (byte[]) o2);
}
if (o1 instanceof char[] chars1 && o2 instanceof char[] chars2) {
return Arrays.equals(chars1, chars2);
if (type1 == char[].class && type2 == char[].class) {
return Arrays.equals((char[]) o1, (char[]) o2);
}
if (o1 instanceof double[] doubles1 && o2 instanceof double[] doubles2) {
return Arrays.equals(doubles1, doubles2);
if (type1 == double[].class && type2 == double[].class) {
return Arrays.equals((double[]) o1, (double[]) o2);
}
if (o1 instanceof float[] floats1 && o2 instanceof float[] floats2) {
return Arrays.equals(floats1, floats2);
if (type1 == float[].class && type2 == float[].class) {
return Arrays.equals((float[]) o1, (float[]) o2);
}
if (o1 instanceof int[] ints1 && o2 instanceof int[] ints2) {
return Arrays.equals(ints1, ints2);
if (type1 == int[].class && type2 == int[].class) {
return Arrays.equals((int[]) o1, (int[]) o2);
}
if (o1 instanceof long[] longs1 && o2 instanceof long[] longs2) {
return Arrays.equals(longs1, longs2);
if (type1 == long[].class && type2 == long[].class) {
return Arrays.equals((long[]) o1, (long[]) o2);
}
if (o1 instanceof short[] shorts1 && o2 instanceof short[] shorts2) {
return Arrays.equals(shorts1, shorts2);
if (type1 == short[].class && type2 == short[].class) {
return Arrays.equals((short[]) o1, (short[]) o2);
}
return false;
}

7
spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java

@ -267,6 +267,13 @@ class ObjectUtilsTests { @@ -267,6 +267,13 @@ class ObjectUtilsTests {
void nullSafeEqualsWithArrays() {
assertThat(ObjectUtils.nullSafeEquals(new String[] {"a", "b", "c"}, new String[] {"a", "b", "c"})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new int[] {1, 2, 3}, new int[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new long[] {1, 2, 3}, new long[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new short[] {1, 2, 3}, new short[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new byte[] {1, 2, 3}, new byte[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new float[] {1, 2, 3}, new float[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new double[] {1, 2, 3}, new double[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new char[] {1, 2, 3}, new char[] {1, 2, 3})).isTrue();
assertThat(ObjectUtils.nullSafeEquals(new boolean[] {true, false, true}, new boolean[] {true, false, true})).isTrue();
}
@Test

Loading…
Cancel
Save