You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/05/25 14:18:54 UTC

[commons-lang] 02/03: Add and use APIs to avoid compiler warnings and use of @SuppressWarnings.

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 27101b4739dd443c35b8ffb287a5b004188d1703
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue May 25 09:57:29 2021 -0400

    Add and use APIs to avoid compiler warnings and use of
    @SuppressWarnings.
    
    - Add and use ArrayUtils.getComponentType(T[]).
    - Add and use ClassUtils.getComponentType(Class<T[]>).
    - Add and use ObjectUtils.getClass(T).
---
 src/changes/changes.xml                            |   3 +
 .../java/org/apache/commons/lang3/ArrayUtils.java  | 121 +++++++--------------
 .../java/org/apache/commons/lang3/ClassUtils.java  |  14 +++
 .../java/org/apache/commons/lang3/ObjectUtils.java |  13 +++
 .../commons/lang3/event/EventListenerSupport.java  |  11 +-
 .../org/apache/commons/lang3/ArrayUtilsTest.java   |  17 ++-
 .../org/apache/commons/lang3/ClassUtilsTest.java   |  11 ++
 .../org/apache/commons/lang3/ObjectUtilsTest.java  |   9 ++
 8 files changed, 104 insertions(+), 95 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7be8bc0..32c1a2e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -55,6 +55,9 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add TriConsumer.</action>
     <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add and use EnumUtils.getFirstEnumIgnoreCase(Class, String, Function, E).</action>
     <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add and use Suppliers.</action>
+    <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add and use ArrayUtils.getComponentType(T[]).</action>
+    <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add and use ClassUtils.getComponentType(Class<T[]>).</action>
+    <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add and use ObjectUtils.getClass(T).</action>
     <!-- UPDATE -->
     <action                   type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump spotbugs-maven-plugin from 4.2.0 to 4.2.3 #735.</action>
     <action                   type="update" dev="ggregory" due-to="Dependabot, XenoAmess">Bump Bump actions/cache from v2.1.4 to v2.1.5 #742, #752.</action>
diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
index 9f115fe..69ccfcb 100644
--- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
@@ -743,17 +743,27 @@ public class ArrayUtils {
      */
     @Deprecated
     public static <T> T[] add(final T[] array, final int index, final T element) {
-        Class<?> clss = null;
+        Class<T> clss = null;
         if (array != null) {
-            clss = array.getClass().getComponentType();
+            clss = getComponentType(array);
         } else if (element != null) {
-            clss = element.getClass();
+            clss = ObjectUtils.getClass(element);
         } else {
             throw new IllegalArgumentException("Array and element cannot both be null");
         }
-        @SuppressWarnings("unchecked") // the add method creates an array of type clss, which is type T
-        final T[] newArray = (T[]) add(array, index, element, clss);
-        return newArray;
+        return (T[]) add(array, index, element, clss);
+    }
+
+    /**
+     * Gets an array's component type.
+     *
+     * @param <T> The array type.
+     * @param array The array.
+     * @return The component type.
+     * @since 3.13.0
+     */
+    public static <T> Class<T> getComponentType(final T[] array) {
+        return ClassUtils.getComponentType(ObjectUtils.getClass(array));
     }
 
     /**
@@ -3102,7 +3112,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
         }
 
-        final Class<?> type = array.getClass().getComponentType();
+        final Class<T> type = getComponentType(array);
         @SuppressWarnings("unchecked") // OK, because array and values are of type T
         final
         T[] result = (T[]) Array.newInstance(type, array.length + values.length);
@@ -3786,10 +3796,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
-        if (isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if (isEmpty(array) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -3832,10 +3839,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -3880,10 +3884,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 2.1
      */
     public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -3943,10 +3944,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
-        if (isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if (isEmpty(array) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -3978,10 +3976,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
-        if (isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if (isEmpty(array) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -4027,10 +4022,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
-        if (isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if (isEmpty(array) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -4073,10 +4065,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -4119,10 +4108,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -4165,10 +4151,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -4219,10 +4202,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
      */
     public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
+        if ((array == null) || (startIndex < 0)) {
             return INDEX_NOT_FOUND;
         }
         if (startIndex >= array.length) {
@@ -6982,10 +6962,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final boolean[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7061,10 +7038,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final byte[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7140,10 +7114,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final char[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7219,10 +7190,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final double[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7298,10 +7266,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final float[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7377,10 +7342,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final int[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7456,10 +7418,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final long[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7537,10 +7496,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final Object[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -7616,10 +7572,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
      * @since 3.5
      */
     public static void shift(final short[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
-        if (array == null) {
-            return;
-        }
-        if (startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
+        if ((array == null) || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
             return;
         }
         if (startIndexInclusive < 0) {
@@ -8243,7 +8196,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd
             endIndexExclusive = array.length;
         }
         final int newSize = endIndexExclusive - startIndexInclusive;
-        final Class<?> type = array.getClass().getComponentType();
+        final Class<T> type = getComponentType(array);
         if (newSize <= 0) {
             @SuppressWarnings("unchecked") // OK, because array is of type T
             final T[] emptyArray = (T[]) Array.newInstance(type, 0);
diff --git a/src/main/java/org/apache/commons/lang3/ClassUtils.java b/src/main/java/org/apache/commons/lang3/ClassUtils.java
index 2f95b07..5a81ad5 100644
--- a/src/main/java/org/apache/commons/lang3/ClassUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ClassUtils.java
@@ -1121,6 +1121,20 @@ public class ClassUtils {
     }
 
     /**
+     * Delegates to {@link Class#getComponentType()} using generics.
+     *
+     * @param <T> The array class type.
+     * @param cls A class or null.
+     * @return The array component type or null.
+     * @see Class#getComponentType()
+     * @since 3.13.0
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Class<T> getComponentType(final Class<T[]> cls) {
+        return cls == null ? null : (Class<T>) cls.getComponentType();
+    }
+
+    /**
      * <p>Returns the desired Method much like {@code Class.getMethod}, however
      * it ensures that the returned Method is from a public class or interface and not
      * from an anonymous inner class. This means that the Method is invokable and
diff --git a/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
index 4bfac7e..78787fa 100644
--- a/src/main/java/org/apache/commons/lang3/ObjectUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
@@ -674,6 +674,19 @@ public class ObjectUtils {
     }
 
     /**
+     * Delegates to {@link Object#getClass()} using generics.
+     *
+     * @param <T> The argument type or null.
+     * @param object The argument.
+     * @return The argument Class or null.
+     * @since 3.13.0
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Class<T> getClass(final T object) {
+        return object == null ? null : (Class<T>) object.getClass();
+    }
+
+    /**
      * <p>Executes the given suppliers in order and returns the first return
      * value where a value other than {@code null} is returned.
      * Once a non-{@code null} value is obtained, all following suppliers are
diff --git a/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java b/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
index 315a612..8d51a21 100644
--- a/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
+++ b/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
@@ -30,6 +30,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.Validate;
 
 /**
@@ -266,14 +267,11 @@ public class EventListenerSupport<L> implements Serializable {
      */
     private void readObject(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
         @SuppressWarnings("unchecked") // Will throw CCE here if not correct
-        final
-        L[] srcListeners = (L[]) objectInputStream.readObject();
+        final L[] srcListeners = (L[]) objectInputStream.readObject();
 
         this.listeners = new CopyOnWriteArrayList<>(srcListeners);
 
-        @SuppressWarnings("unchecked") // Will throw CCE here if not correct
-        final
-        Class<L> listenerInterface = (Class<L>) srcListeners.getClass().getComponentType();
+        final Class<L> listenerInterface = ArrayUtils.getComponentType(srcListeners);
 
         initializeTransientFields(listenerInterface, Thread.currentThread().getContextClassLoader());
     }
@@ -285,8 +283,7 @@ public class EventListenerSupport<L> implements Serializable {
      */
     private void initializeTransientFields(final Class<L> listenerInterface, final ClassLoader classLoader) {
         @SuppressWarnings("unchecked") // Will throw CCE here if not correct
-        final
-        L[] array = (L[]) Array.newInstance(listenerInterface, 0);
+        final L[] array = (L[]) Array.newInstance(listenerInterface, 0);
         this.prototypeArray = array;
         createProxy(listenerInterface, classLoader);
     }
diff --git a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
index 4dddb05..c69cd39 100644
--- a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
@@ -46,6 +46,7 @@ import org.junit.jupiter.api.Test;
 public class ArrayUtilsTest {
 
     private class TestClass {
+        // empty
     }
 
     /** A predefined seed used to initialize {@link Random} in order to get predictable results */
@@ -213,13 +214,16 @@ public class ArrayUtilsTest {
 
     @Test
     public void testContains_LANG_1261() {
+
         class LANG1261ParentObject {
             @Override
             public boolean equals(final Object o) {
                 return true;
             }
         }
+
         class LANG1261ChildObject extends LANG1261ParentObject {
+            // empty.
         }
 
         final Object[] array = new LANG1261ChildObject[]{new LANG1261ChildObject()};
@@ -404,6 +408,15 @@ public class ArrayUtilsTest {
     }
 
     @Test
+    public void testGetComponentType() {
+        final TestClass[] newArray = {};
+        // No type-cast required.
+        final Class<TestClass> componentType = ArrayUtils.getComponentType(newArray);
+        assertEquals(TestClass.class, componentType);
+        assertNull(ArrayUtils.getComponentType(null));
+    }
+
+    @Test
     public void testGetDefault() {
         // null default
         {
@@ -656,7 +669,6 @@ public class ArrayUtilsTest {
         assertEquals(emptySet, ArrayUtils.indexesOf(array, 'e', 0));
     }
 
-    @SuppressWarnings("cast")
     @Test
     public void testIndexesOfDouble() {
         double[] array = null;
@@ -700,7 +712,6 @@ public class ArrayUtilsTest {
         assertEquals(testSet, ArrayUtils.indexesOf(array, 1.00001324, 0.0001));
     }
 
-    @SuppressWarnings("cast")
     @Test
     public void testIndexesOfDoubleWithStartIndex() {
         double[] array = null;
@@ -753,7 +764,6 @@ public class ArrayUtilsTest {
         assertEquals(testSet, ArrayUtils.indexesOf(array, 1.00001324, 0, 0.0001));
     }
 
-    @SuppressWarnings("cast")
     @Test
     public void testIndexesOfFloat() {
         float[] array = null;
@@ -776,7 +786,6 @@ public class ArrayUtilsTest {
         assertEquals(emptySet, ArrayUtils.indexesOf(array, 99));
     }
 
-    @SuppressWarnings("cast")
     @Test
     public void testIndexesOfFloatWithStartIndex() {
         float[] array = null;
diff --git a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
index 9af84c4..010d487 100644
--- a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
@@ -1235,6 +1235,17 @@ public class ClassUtilsTest  {
     }
 
     @Test
+    public void testGetComponentType() {
+        final CX[] newArray = {};
+        @SuppressWarnings("unchecked")
+        final Class<CX[]> classCxArray = (Class<CX[]>) newArray.getClass();
+        // No type-cast required.
+        final Class<CX> componentType = ClassUtils.getComponentType(classCxArray);
+        assertEquals(CX.class, componentType);
+        assertNull(ClassUtils.getComponentType(null));
+    }
+
+    @Test
     public void testGetInnerClass() throws ClassNotFoundException {
         assertEquals( Inner.DeeplyNested.class, ClassUtils.getClass( "org.apache.commons.lang3.ClassUtilsTest.Inner.DeeplyNested" ) );
         assertEquals( Inner.DeeplyNested.class, ClassUtils.getClass( "org.apache.commons.lang3.ClassUtilsTest.Inner$DeeplyNested" ) );
diff --git a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
index 7f7a1cd..9b2991a 100644
--- a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
@@ -422,6 +422,15 @@ public class ObjectUtilsTest {
     }
 
     @Test
+    public void testGetClass() {
+        final String[] newArray = ArrayUtils.EMPTY_STRING_ARRAY;
+        // No type-cast required.
+        final Class<String[]> cls = ObjectUtils.getClass(newArray);
+        assertEquals(String[].class, cls);
+        assertNull(ObjectUtils.getClass(null));
+    }
+
+    @Test
     public void testGetFirstNonNull() {
         // first non null
         assertEquals("", ObjectUtils.getFirstNonNull(() -> null, () -> ""));