public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
        if (array == null) {
            return null;
        }
        if (startIndexInclusive < 0) {
            startIndexInclusive = 0;
        }
        if (endIndexExclusive > array.length) {
            endIndexExclusive = array.length;
        }
        int newSize = endIndexExclusive - startIndexInclusive;
        Class<?> type = array.getClass().getComponentType();
        if (newSize <= 0) {
            @SuppressWarnings("unchecked") // OK, because array is of type T
            final T[] emptyArray = (T[]) Array.newInstance(type, 0);
            return emptyArray;
        }
        @SuppressWarnings("unchecked") // OK, because array is of type T
        T[] subarray = (T[]) Array.newInstance(type, newSize);
        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
        return subarray;
    }
<p>Produces a new array containing the elements between
the start and end indices.</p>

<p>The start index is inclusive, the end index exclusive.
Null array input produces null output.</p>

<p>The component type of the subarray is always the same as
that of the input array. Thus, if the input is an array of type
{@code Date}, the following usage is envisaged:</p>

<pre>
Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
</pre>

@param <T> the component type of the array
@param array  the array
@param startIndexInclusive  the starting index. Undervalue (&lt;0)
     is promoted to 0, overvalue (&gt;array.length) results
     in an empty array.
@param endIndexExclusive  elements up to endIndex-1 are present in the
     returned subarray. Undervalue (&lt; startIndex) produces
     empty array, overvalue (&gt;array.length) is demoted to
     array length.
@return a new array containing the elements between
     the start and end indices.
@since 2.1
android/android_framework/base/src/main/java/lang3/ArrayUtils.java