{"record":{"id":"6ff531ed55c7ef0d","repo":"Blankj/AndroidUtilCode","slug":"array-has-incompatible-type-6ff531","errorCode":null,"errorMessage":"Array has incompatible type: {}","messagePattern":"Array has incompatible type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java","lineNumber":1169,"sourceCode":"                return Arrays.deepToString((Object[]) object);\n            } else if (object instanceof boolean[]) {\n                return Arrays.toString((boolean[]) object);\n            } else if (object instanceof byte[]) {\n                return Arrays.toString((byte[]) object);\n            } else if (object instanceof char[]) {\n                return Arrays.toString((char[]) object);\n            } else if (object instanceof double[]) {\n                return Arrays.toString((double[]) object);\n            } else if (object instanceof float[]) {\n                return Arrays.toString((float[]) object);\n            } else if (object instanceof int[]) {\n                return Arrays.toString((int[]) object);\n            } else if (object instanceof long[]) {\n                return Arrays.toString((long[]) object);\n            } else if (object instanceof short[]) {\n                return Arrays.toString((short[]) object);\n            }\n            throw new IllegalArgumentException(\"Array has incompatible type: \" + object.getClass());\n        }\n    }\n\n    private static <T> Class getTypeClassFromParadigm(final IFormatter<T> formatter) {\n        Type[] genericInterfaces = formatter.getClass().getGenericInterfaces();\n        Type type;\n        if (genericInterfaces.length == 1) {\n            type = genericInterfaces[0];\n        } else {\n            type = formatter.getClass().getGenericSuperclass();\n        }\n        type = ((ParameterizedType) type).getActualTypeArguments()[0];\n        while (type instanceof ParameterizedType) {\n            type = ((ParameterizedType) type).getRawType();\n        }\n        String className = type.toString();\n        if (className.startsWith(\"class \")) {\n            className = className.substring(6);","sourceCodeStart":1151,"sourceCodeEnd":1187,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java#L1151-L1187","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Convert arrays to a List or to a String before passing to LogUtils: log Arrays.asList(arr) or Arrays.toString(arr) instead.","Register a custom IFormatter<T> via LogUtils.getConfig().addFormatter() to handle the specific type.","If hitting this with a standard primitive array, check for class-loader or instrumentation conflicts in your build.","Wrap the log call in a try-catch for IllegalArgumentException to degrade gracefully."],"exampleFix":"// before\nString[] names = {\"Alice\", \"Bob\"};\nLogUtils.d(names); // triggers array2String internally\n\n// after\nString[] names = {\"Alice\", \"Bob\"};\nLogUtils.d(Arrays.toString(names)); // pre-convert to string","handlingStrategy":"validation","validationCode":"// Pre-convert arrays to String before logging\nObject arg = getLoggableValue();\nif (arg != null && arg.getClass().isArray()) {\n    // Safe: array2String handles Object[] and all primitive arrays\n    LogUtils.d(arg);\n} else {\n    LogUtils.d(String.valueOf(arg));\n}","typeGuard":"static boolean isStandardArrayType(Object obj) {\n    if (obj == null) return false;\n    Class<?> componentType = obj.getClass().getComponentType();\n    if (componentType == null) return false; // not an array\n    return componentType.isPrimitive()\n        || componentType == Object.class\n        || componentType == String.class;\n}","tryCatchPattern":"try {\n    LogUtils.d(myArray);\n} catch (IllegalArgumentException e) {\n    // Fallback: convert manually\n    LogUtils.d(java.util.Arrays.toString((Object[]) myArray));\n}","preventionTips":["Convert arrays to String with Arrays.toString() or Arrays.asList() before logging.","Register custom IFormatter<T> for non-standard types via LogUtils.getConfig().addFormatter().","Wrap log calls in try-catch if logging user-generated or dynamic content.","Test logging paths with edge-case inputs (nested arrays, empty arrays, Object[] of custom types)."],"tags":["java","android","logging","array","serialization"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}