didi/DoKit · error · ReflectedException
Caller [" + caller + "] is not a instance of type [" + mType
Error message
Caller [" + caller + "] is not a instance of type [" + mType + "]!
What it means
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.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/util/Reflector.java:96
@SuppressWarnings("unchecked")
public <R> R newInstance(@Nullable Object ... initargs) throws ReflectedException {
if (mConstructor == null) {
throw new ReflectedException("Constructor was null!");
}
try {
return (R) mConstructor.newInstance(initargs);
} catch (InvocationTargetException e) {
throw new ReflectedException("Oops!", e.getTargetException());
} catch (Throwable e) {
throw new ReflectedException("Oops!", e);
}
}
protected Object checked(@Nullable Object caller) throws ReflectedException {
if (caller == null || mType.isInstance(caller)) {
return caller;
}
throw new ReflectedException("Caller [" + caller + "] is not a instance of type [" + mType + "]!");
}
protected void check(@Nullable Object caller, @Nullable Member member, @NonNull String name) throws ReflectedException {
if (member == null) {
throw new ReflectedException(name + " was null!");
}
if (caller == null && !Modifier.isStatic(member.getModifiers())) {
throw new ReflectedException("Need a caller!");
}
checked(caller);
}
public Reflector bind(@Nullable Object caller) throws ReflectedException {
mCaller = checked(caller);
return this;
}
public Reflector unbind() {View on GitHub (pinned to 626827cddb)
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
Example fix
// before
Reflector.on(View.class).field("mAttachInfo").get(someViewGroup); // ok if subclass
Reflector.on(TextView.class).field("mLayout").get(someImageView); // throws
// after
Reflector.on(TextView.class).field("mLayout").get((TextView) someView); Defensive patterns
Strategy: type-guard
Validate before calling
if (caller != null && !mType.isInstance(caller)) {
throw new IllegalArgumentException(caller.getClass() + " is not " + mType);
} Type guard
static boolean isInstanceOf(Object caller, Class<?> type) {
return caller == null || type.isInstance(caller);
} Try / catch
try {
r.get(caller);
} catch (ReflectedException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Caller [")) { /* wrong caller class */ }
} Prevention
- Create the Reflector from the class that declares the member
- Beware duplicate classes across plugin classloaders — compare ClassLoader identity
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Constructor was null!
- name + " was null!"
- Need a caller!
- Not an array: " + array.getClass()
- Unsupported object type: " + object.getClass().getName()
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/a8e7d4c3c1e13a73.
Report an issue: GitHub.