Blankj/AndroidUtilCode · error · IllegalArgumentException

Array has incompatible type: {}

Error message

Array has incompatible type: {}

What it means

LogUtils.array2String() converts arrays to string representations for logging. It checks Object[] (via deepToString) and all eight primitive array types. If the object passes none of these instanceof checks, it throws IllegalArgumentException with the class name. In practice this should be unreachable for any real array type, but it fires if a non-array object is passed or in JVM edge cases with custom array-like types.

Source

Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java:1169

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

    private static <T> Class getTypeClassFromParadigm(final IFormatter<T> formatter) {
        Type[] genericInterfaces = formatter.getClass().getGenericInterfaces();
        Type type;
        if (genericInterfaces.length == 1) {
            type = genericInterfaces[0];
        } else {
            type = formatter.getClass().getGenericSuperclass();
        }
        type = ((ParameterizedType) type).getActualTypeArguments()[0];
        while (type instanceof ParameterizedType) {
            type = ((ParameterizedType) type).getRawType();
        }
        String className = type.toString();
        if (className.startsWith("class ")) {
            className = className.substring(6);

View on GitHub (pinned to 7b4caf9e54)

Solutions

  1. Convert arrays to a List or to a String before passing to LogUtils: log Arrays.asList(arr) or Arrays.toString(arr) instead.
  2. Register a custom IFormatter<T> via LogUtils.getConfig().addFormatter() to handle the specific type.
  3. If hitting this with a standard primitive array, check for class-loader or instrumentation conflicts in your build.
  4. Wrap the log call in a try-catch for IllegalArgumentException to degrade gracefully.

Example fix

// before
String[] names = {"Alice", "Bob"};
LogUtils.d(names); // triggers array2String internally

// after
String[] names = {"Alice", "Bob"};
LogUtils.d(Arrays.toString(names)); // pre-convert to string
Defensive patterns

Strategy: validation

Validate before calling

// Pre-convert arrays to String before logging
Object arg = getLoggableValue();
if (arg != null && arg.getClass().isArray()) {
    // Safe: array2String handles Object[] and all primitive arrays
    LogUtils.d(arg);
} else {
    LogUtils.d(String.valueOf(arg));
}

Type guard

static boolean isStandardArrayType(Object obj) {
    if (obj == null) return false;
    Class<?> componentType = obj.getClass().getComponentType();
    if (componentType == null) return false; // not an array
    return componentType.isPrimitive()
        || componentType == Object.class
        || componentType == String.class;
}

Try / catch

try {
    LogUtils.d(myArray);
} catch (IllegalArgumentException e) {
    // Fallback: convert manually
    LogUtils.d(java.util.Arrays.toString((Object[]) myArray));
}

Prevention

When it happens

Trigger: Internally, LogUtils calls array2String() when it detects the logged object is an array. The error fires if the object is somehow classified as an array by upstream code but doesn't match any known array instanceof check — theoretically impossible for standard JVM array types, but could occur with bytecode manipulation, custom class loaders, or if a non-array slips through a code path that expects an array.

Common situations: Logging a custom type that extends an array-like interface under a modified class loader; instrumentation frameworks that wrap arrays; edge cases in Android Runtime array handling; deserialized array objects that lose their array identity.

Related errors


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/6ff531ed55c7ef0d. Report an issue: GitHub.