didi/DoKit · error · IllegalArgumentException

Array has incompatible type: " + array.getClass()

Error message

Array has incompatible type: " + array.getClass()

What it means

Thrown by ArrayUtils.toString(Object) after its instanceof chain over boolean[], byte[], char[], double[], float[], int[], long[], short[] and Object[] fails. Only single-dimension arrays of those exact types are supported; every other runtime type (nested arrays, custom objects, non-array references) reaches the throw. Correct callers never see it; it guards against unsupported array shapes.

Source

Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/ArrayUtils.java:2138

            return Arrays.deepToString((Object[]) array);
        } else if (array instanceof boolean[]) {
            return Arrays.toString((boolean[]) array);
        } else if (array instanceof byte[]) {
            return Arrays.toString((byte[]) array);
        } else if (array instanceof char[]) {
            return Arrays.toString((char[]) array);
        } else if (array instanceof double[]) {
            return Arrays.toString((double[]) array);
        } else if (array instanceof float[]) {
            return Arrays.toString((float[]) array);
        } else if (array instanceof int[]) {
            return Arrays.toString((int[]) array);
        } else if (array instanceof long[]) {
            return Arrays.toString((long[]) array);
        } else if (array instanceof short[]) {
            return Arrays.toString((short[]) array);
        }
        throw new IllegalArgumentException("Array has incompatible type: " + array.getClass());
    }

    public interface Closure<E> {
        void execute(int index, E item);
    }
}

View on GitHub (pinned to 626827cddb)

Solutions

  1. Use java.util.Arrays.deepToString(...) for nested arrays instead of ArrayUtils.toString.
  2. Guard with object.getClass().isArray() && object.getClass().getComponentType().isPrimitive() || component type is Object before calling.
  3. If the value may not be an array at all, String.valueOf(object) is the safe generic fallback.

Example fix

// before
int[][] grid = {{1,2},{3,4}};
String s = ArrayUtils.toString(grid); // throws

// after
int[][] grid = {{1,2},{3,4}};
String s = java.util.Arrays.deepToString(grid);
Defensive patterns

Strategy: type-guard

Validate before calling

if (object != null && object.getClass().isArray()
        && !object.getClass().getComponentType().isArray()) {
    s = ArrayUtils.toString(object);
} else {
    s = java.util.Arrays.deepToString((Object[]) object); // nested
}

Type guard

static boolean isFlatPrimitiveOrObjectArray(Object o) {
    if (o == null || !o.getClass().isArray()) return false;
    return !o.getClass().getComponentType().isArray();
}

Try / catch

try { text = ArrayUtils.toString(value); } catch (IllegalArgumentException e) { text = String.valueOf(value); }

Prevention

When it happens

Trigger: Calling ArrayUtils.toString on a multidimensional array such as int[][] or String[][] (the outer array is typed Object[] only if the inner arrays are Object[]), or on a non-array Object. Nested primitive arrays like float[][] do not match float[] and throw.

Common situations: Debug/dump utilities that stringify arbitrary fields via reflection; matrix or coordinate data stored as int[][]; generics erasure delivering an unexpected runtime type to a logging helper.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/ee8702e5967529b8. Report an issue: GitHub.