【问题标题】:Disappearing default constructors消失的默认构造函数
【发布时间】:2014-06-14 06:37:45
【问题描述】:

我收到了一些包含以下堆栈跟踪(名称已更改)的崩溃报告:

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();
}

这一定是发生了,否则我一开始就无法编译应用程序。那么导致这些崩溃的原因是什么?


编辑: 以下是使用 javap 反编译 ProGuard-ed MyApplication.class 的部分输出:
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
}

默认构造函数肯定在里面,而且是公开的。

【问题讨论】:

  • 您是否尝试过显式声明构造函数?这样做的时候你还有问题吗?我知道它不会解释为什么这目前不起作用,但我只是在这里很好奇。
  • 如果你可以访问编译后的资源,运行javap并检查这样的构造函数是否存在并且是公共的。
  • @Joffrey,我自己从未见过这种崩溃,只是在崩溃报告中。我可以显式声明构造函数,但要过一段时间才能看到它是否“在野外”解决了问题。
  • @SotiriosDelimanolis,我将javap 的输出添加到问题中。

标签: java android dalvik default-constructor


【解决方案1】:

注意:在这种情况下,这不是问题,但如果您因为遇到相同的症状而阅读此问题,可能你……

根据我对Java规范的理解,这意味着下面的构造函数应该被编译器隐式插入

public MyApplication() {
    super();
}

只有当它是一个 public 类时才会出现这种情况。来自section 8.8.9 of the JLS

默认构造函数具有与类相同的可访问性(第 6.6 节)。

因此,如果您的类被声明为具有public 以外的任何访问权限,则构造函数也不会是公共的。

你没有展示你的类声明,但你首先应该检查的是它是公开的。

【讨论】:

  • MyApplication 确实是public
  • @kpozin:好的 - 将此答案留给处于类似位置的其他人检查,但会进行编辑以表明这不是问题。
猜你喜欢
  • 2016-07-23
  • 2023-03-20
  • 2012-08-01
  • 2010-10-30
  • 2014-05-15
  • 2011-03-12
  • 2018-04-23
相关资源
最近更新 更多