didi/DoKit · error · ReflectedException
Constructor was null!
Error message
Constructor was null!
What it means
Reflector.newInstance(Object...) throws ReflectedException("Constructor was null!") when the internal mConstructor field is null — i.e. newInstance is called before constructor(...) ever successfully selected one, or after a later field()/method() call reset mConstructor to null. It is a strict usage-ordering guard, not a JVM failure.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/util/Reflector.java:81
}
public Reflector constructor(@Nullable Class<?>... parameterTypes) throws ReflectedException {
try {
mConstructor = mType.getDeclaredConstructor(parameterTypes);
mConstructor.setAccessible(true);
mField = null;
mMethod = null;
return this;
} catch (Throwable e) {
throw new ReflectedException("Oops!", e);
}
}
@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 {View on GitHub (pinned to 626827cddb)
Solutions
- Always chain .constructor(parameterTypes) immediately before .newInstance(args)
- Do not interleave .field()/.method() between .constructor() and .newInstance() — they clear mConstructor
- Use a fresh Reflector.on(...) instance per member kind if you need several lookups
Example fix
// before
Reflector.on(cls).newInstance("arg");
// after
Reflector.on(cls).constructor(String.class).newInstance("arg"); Defensive patterns
Strategy: validation
Validate before calling
// ensure constructor is selected before newInstance
if (r == null /* or mConstructor unset */) { throw new IllegalStateException("call constructor(...) first"); } Prevention
- Keep .constructor(...).newInstance(...) in one fluent chain
- Use one Reflector instance per member kind; field()/method() clear mConstructor
When it happens
Trigger: Calling Reflector.on(SomeClass.class).newInstance(...) directly without a preceding .constructor(...); or calling .field("x")/.method("y") after .constructor(...) (both null out mConstructor) and then newInstance again.
Common situations: Chained fluent calls reordered during refactoring; copy-paste of a reflect snippet that omitted the constructor step; interleaving constructor and field/method lookups on the same Reflector instance.
Related errors
- name + " was null!"
- Caller [" + caller + "] is not a instance of type [" + mType
- Need a caller!
- Unsupported object type: " + object.getClass().getName()
- No similar method ${name} with params ${types} could be foun
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/c8e4bba0d94a8902.
Report an issue: GitHub.