Исчезающие конструкторы по умолчанию
Я получил несколько отчетов о сбоях со следующими следами стека (имена изменены):
Caused by: java.lang.InstantiationException: can't instantiate class com.example.MyApplication; no empty constructor
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.Instrumentation.newApplication(Instrumentation.java:997)
at android.app.Instrumentation.newApplication(Instrumentation.java:982)
at android.app.LoadedApk.makeApplication(LoadedApk.java:496)
... 11 more
java.lang.RuntimeException: Unable to instantiate application com.example.MyApplication: java.lang.InstantiationException: can't instantiate class com.example.MyApplication; no empty constructor
at android.app.LoadedApk.makeApplication(LoadedApk.java:501)
android.app.Application
имеет явный беспараметрический конструктор:
public Application() {
super(null);
}
MyApplication
наследуется от android.app.Application
и не имеет явных конструкторов вообще. Согласно моему пониманию спецификации Java, это означает, что следующий конструктор должен быть неявно вставлен компилятором:
public MyApplication() {
super();
}
Это должно было произойти, иначе я бы никогда не смог скомпилировать приложение. Так что может быть причиной этих сбоев?
РЕДАКТИРОВАТЬ: Вот часть вывода из декомпиляции ProGuard-ed
MyApplication.class
с javap
:Compiled from "MyApplication.java"
public class com.example.MyApplication extends android.app.Application {
public com.example.MyApplication();
Signature: ()V
public void onCreate();
Signature: ()V
public void onLowMemory();
Signature: ()V
public void onTrimMemory(int);
Signature: (I)V
// ... some other methods ...
static {};
Signature: ()V
}
Конструктор по умолчанию определенно здесь, и он общедоступен.
1 ответ
Примечание: в этом случае проблема не возникла, но если вы читаете этот вопрос, потому что столкнулись с тем же симптомом, это может быть проблемой для вас...
Согласно моему пониманию спецификации Java, это означает, что следующий конструктор должен быть неявно вставлен компилятором
public MyApplication() { super(); }
Это только в том случае, если это публичный класс. Из раздела 8.8.9 JLS:
Конструктор по умолчанию имеет ту же доступность, что и класс (§6.6).
Так что если ваш класс объявлен как имеющий какой-либо доступ, кроме public
конструктор тоже не будет публичным.
Вы не показали объявление своего класса, но первое, что вы должны проверить, это то, что оно публично.