如何添加默认构造函数

How to add a default contructor

希望我在这里没有重复问题,但我在堆栈交换中找到的所有问题似乎都不符合我的需要。

这是我的代码片段:

public class custom_row_adapter extends ArrayAdapter<Integer> {
     custom_row_adapter(Context context, ArrayList<Integer> picId, String url, String fullUrl) {
         super(context, R.layout.activity_custom_row_adapter, picId);
}
     //Do stuff

应用程序中的一切正常,现在我尝试生成一个签名的 apk,但我收到一个不错的小错误,我需要一个默认构造函数。所以我决定添加一个,现在我的代码如下所示:

public class custom_row_adapter extends ArrayAdapter<Integer> {
    public custom_row_adapter() {
        super();
}
     custom_row_adapter(Context context, ArrayList<Integer> picId, String url, String fullUrl) {
         super(context, R.layout.activity_custom_row_adapter, picId);
}
//Do Stuff

现在我收到一个新错误,它无法为 ArrayAdapter()

找到合适的构造函数

所以我在 google 上找到了一些帖子,其中一个告诉我可以通过在 Inspections 选项卡中搜索 Instantiable 并将其设置为 WARNING 来绕过该错误,它将修复它。没用。

那么我该如何解决这个问题呢?提前致谢。

编辑:对于那些说我可以添加 public custom_row_adpater(){}

EDIT 2:这里有更多图片,注意左下角的错误:

什么在调试中有效:

Paul G 的回答:

默认构造函数:

无构造函数:

因为ArrayAdapter没有定义无参构造函数。这就是当您调用不带参数的 super() 时编译器要查找的内容。它至少需要一个上下文和一个资源 (int) 来初始化自己。

ArrayAdapter 没有默认的 i.e.zero-param 构造函数,因此您必须重写其中一个它有的构造函数。您可以在此处找到更多信息

public class custom_row_adapter extends ArrayAdapter<Integer> { 
    public custom_row_adapter(Context context, int resource) {
        super(context, resource); 
    }

由于您正在扩展 ArrayAdapter,您可以从这里实例化您的对象:

Custom_row_adapter customAdapter = new Custom_row_adapter(this, android.R.layout.simple_spinner_item, insertIntegerArray);

如果您想在 class 中添加一些额外参数,请创建自定义 contructor:

 public Custom_row_adapter(Context context, int resource, Integer[] array, arg extraArg) {
    super(context, resource, array);
    this.extraArg = extraArg;
 }

我的建议是将您的 class 重命名为 Custom_row_adapter。 class 名称以 大写 字符开头是一个好习惯。

来自 JavaSE 文档:

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

为默认构造函数提供一个空的构造函数主体与进行超级调用相同,即

public custom_row_adapter() {
    super();
}

相同
public custom_row_adapter() {}

所以会报错,因为超类中没有默认构造函数,需要显式调用构造函数。在这种情况下,您可以重载构造函数并使用 this(args) 调用它,或者使用 super(args) 调用某些超类构造函数。

参考: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.7

此错误意味着出于某种原因,lint(错误地)认为您的适配器应该是可实例化的。这适用于可能由系统实例化的对象,如活动、广播接收器,但不适用于适配器,因为它们总是在应用程序代码中实例化。例如 ArrayAdapterSimpleCursorAdapter 等常用适配器没有默认构造函数。

您可以尝试让 Android Studio 恢复正常,例如更新构建工具、清理工作区、删除 build 目录...如果它不起作用您可以添加请求的(和无用的)默认构造函数:

public custom_row_adapter() {
    super(null , 0);
    throw new RuntimeException("This is a workaround and should not be used");
}

我希望我明白你在问什么。

解决方案

因为 ArrayAdapter 没有默认的“无参数”构造函数,您必须提供一些参数。 IE。而不是把

public custom_row_adapter() {
    super();
}

您反而需要指定(至少)两个参数。有关详细信息,请参阅 Javadocs

public custom_row_adapter() {
    super(context, resource);
}

什么是contextresource需要你自己决定。由于您可能不需要此构造函数,因此它们可能是 null 和一些 int,例如 0-1.

为什么

默认情况下,当没有为您的 class 提供构造函数时,Java 会自动为您构建一个什么都不做(本质上)的构造函数。但是,一旦您创建另一个构造函数,默认构造函数 (custom_row_adapter()) 就会“消失”。有关更多信息,请参阅 this post

此外,默认情况下,无参数构造函数 (custom_row_adapter()) 的第一次调用隐式为 super();(请参阅 Java SE)。由于 ArrayAdapter 没有默认的无参数构造函数,因此这是无效的,您必须为其提供参数。