Limitation: It's not work if input array is null.
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;
        }
        Class<?> type = array.getClass().getComponentType();
        int newSize = endIndexExclusive - startIndexInclusive;
        if (newSize < 0) {
            final T[] emptyArray = (T[]) Array.newInstance(type, 0);
            return emptyArray;
        }
        T[] subarray = (T[]) Array.newInstance(type, newSize);
        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
        return subarray;
    }
public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive, Class<T>> clazz) {
     T[] emptyArray = (T[]) Array.newInstance(clazz, 0);
        if (array == null) {
            return emptyArray;
        }
        if (startIndexInclusive < 0) {
            startIndexInclusive = 0;
        }
        if (endIndexExclusive > array.length) {
            endIndexExclusive = array.length;
        }
        if (newSize < 0) {
            return emptyArray;
        }
        T[] subarray = (T[]) Array.newInstance(clazz, newSize);
        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
        return subarray;
    }