{"record":{"id":"a8e7d4c3c1e13a73","repo":"didi/DoKit","slug":"caller-caller-is-not-a-instance-of-type","errorCode":null,"errorMessage":"Caller [\" + caller + \"] is not a instance of type [\" + mType + \"]!","messagePattern":"Caller \\[\" \\+ caller \\+ \"\\] is not a instance of type \\[\" \\+ mType \\+ \"\\]!","errorType":"validation","errorClass":"ReflectedException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/util/Reflector.java","lineNumber":96,"sourceCode":"    @SuppressWarnings(\"unchecked\")\n    public <R> R newInstance(@Nullable Object ... initargs) throws ReflectedException {\n        if (mConstructor == null) {\n            throw new ReflectedException(\"Constructor was null!\");\n        }\n        try {\n            return (R) mConstructor.newInstance(initargs);\n        } catch (InvocationTargetException e) {\n            throw new ReflectedException(\"Oops!\", e.getTargetException());\n        } catch (Throwable e) {\n            throw new ReflectedException(\"Oops!\", e);\n        }\n    }\n    \n    protected Object checked(@Nullable Object caller) throws ReflectedException {\n        if (caller == null || mType.isInstance(caller)) {\n            return caller;\n        }\n        throw new ReflectedException(\"Caller [\" + caller + \"] is not a instance of type [\" + mType + \"]!\");\n    }\n    \n    protected void check(@Nullable Object caller, @Nullable Member member, @NonNull String name) throws ReflectedException {\n        if (member == null) {\n            throw new ReflectedException(name + \" was null!\");\n        }\n        if (caller == null && !Modifier.isStatic(member.getModifiers())) {\n            throw new ReflectedException(\"Need a caller!\");\n        }\n        checked(caller);\n    }\n    \n    public Reflector bind(@Nullable Object caller) throws ReflectedException {\n        mCaller = checked(caller);\n        return this;\n    }\n    \n    public Reflector unbind() {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/util/Reflector.java#L78-L114","documentation":"Reflector.checked(Object caller) validates that the caller object is an instance of the Reflector's bound type (mType). If caller is non-null but not an mType instance, it throws ReflectedException with the message 'Caller [...] is not a instance of type [...]!'. It guards against invoking members on an object of the wrong class.","triggerScenarios":"Calling get(caller)/set(caller,...)/callByCaller(caller,...) with an object whose class differs from the class the Reflector was created with; using Reflector.on(A.class) but passing a B instance because the code assumed inheritance that does not exist; passing a subclass when the reflector was bound to an unrelated interface.","commonSituations":"Refactoring where a reflected field lookup was copied to operate on a different view/fragment class; mixing classloaders so isInstance fails despite identical class names; vendor-specific class hierarchies diverging from AOSP.","solutions":["Check the message — it prints both the caller's toString and the expected mType; reconcile which class actually declares the member","Create the Reflector from the class that actually declares the member (walk to the declaring superclass via findField) or pass a caller of that type","If classloader duplication is suspected, compare caller.getClass() and mType and their classloaders before calling"],"exampleFix":"// before\nReflector.on(View.class).field(\"mAttachInfo\").get(someViewGroup); // ok if subclass\nReflector.on(TextView.class).field(\"mLayout\").get(someImageView); // throws\n\n// after\nReflector.on(TextView.class).field(\"mLayout\").get((TextView) someView);","handlingStrategy":"type-guard","validationCode":"if (caller != null && !mType.isInstance(caller)) {\n    throw new IllegalArgumentException(caller.getClass() + \" is not \" + mType);\n}","typeGuard":"static boolean isInstanceOf(Object caller, Class<?> type) {\n    return caller == null || type.isInstance(caller);\n}","tryCatchPattern":"try {\n    r.get(caller);\n} catch (ReflectedException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Caller [\")) { /* wrong caller class */ }\n}","preventionTips":["Create the Reflector from the class that declares the member","Beware duplicate classes across plugin classloaders — compare ClassLoader identity"],"tags":["reflection","type-check","classloader","api-misuse"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}