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).
This commit is contained in:
Gary Gregory 2021-05-25 09:57:29 -04:00
parent 56e525d074
commit 27101b4739
8 changed files with 104 additions and 95 deletions

View File

@ -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>

View File

@ -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);

View File

@ -1120,6 +1120,20 @@ public class ClassUtils {
return getClass(loader, className, initialize);
}
/**
* 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

View File

@ -673,6 +673,19 @@ public class ObjectUtils {
return null;
}
/**
* 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.

View File

@ -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);
}

View File

@ -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()};
@ -403,6 +407,15 @@ public class ArrayUtilsTest {
assertEquals(null, ArrayUtils.get(array1, 1));
}
@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;

View File

@ -1234,6 +1234,17 @@ public class ClassUtilsTest {
assertGetClassReturnsClass( boolean[][].class );
}
@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" ) );

View File

@ -421,6 +421,15 @@ public class ObjectUtilsTest {
assertNull(ObjectUtils.firstNonNull((Object[]) null));
}
@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