Исчезающие конструкторы по умолчанию

Я получил несколько отчетов о сбоях со следующими следами стека (имена изменены):

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конструктор тоже не будет публичным.

Вы не показали объявление своего класса, но первое, что вы должны проверить, это то, что оно публично.

Другие вопросы по тегам