【问题标题】:Possible error in the Android docs code example or am I missing something?Android 文档代码示例中可能存在错误,还是我遗漏了什么?
【发布时间】:2021-12-29 01:13:47
【问题描述】:

我在 Android Studio 中工作时正在研究如何创建一个多选复选框对话框,自然而然地从查看 android 开发人员页面开始并遇到了this guide。他们展示的代码示例是这样的:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    selectedItems = new ArrayList();  // Where we track the selected items
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Set the dialog title
    builder.setTitle(R.string.pick_toppings)
    // Specify the list array, the items to be selected by default (null for none),
    // and the listener through which to receive callbacks when items are selected
           .setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checked the item, add it to the selected items
                       selectedItems.add(which);
                   } else if (selectedItems.contains(which)) {
                       // Else, if the item is already in the array, remove it
                       selectedItems.remove(which);
                   }
               }
           })
    // Set the action buttons
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // User clicked OK, so save the selectedItems results somewhere
                   // or return them to the component that opened the dialog
                   ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   ...
               }
           });

    return builder.create();
}

现在我感兴趣的是:

.setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checked the item, add it to the selected items
                       selectedItems.add(which);
                   } else if (selectedItems.contains(which)) {
                       // Else, if the item is already in the array, remove it
                       selectedItems.remove(which);
                   }
               }
           })

现在我在这里遗漏了什么或者这里的代码有错误?我的意思是,在selectedItems.remove(which) 中对remove() 的调用不会将which 解释为int 而不是Object,从而删除存储在@987654330 中的int 指定位置处的元素@ 而不是从数组中删除实际的int?这是我在阅读代码时假设会发生的事情,也是当我尝试运行导致IndexOutOfBoundsError 的代码时发生的事情。

但是,由于代码来自 Google 本身提供的资源,我觉得很可能是我遗漏了一些东西。如果是这样的话,我错过了什么?如果不是这种情况并且实际上代码中存在错误,那么我很抱歉,因为该主题似乎不再与 stackoverflow 相关。

当谈到如何解决我遇到的问题时,这不是问题,因为我意识到我可以简单地做一些类似selectedItems.remove((Integer) which)selectedItems.remove(Integer.valueOf(which)) 的事情。我只是对正在发生的事情感到困惑。

【问题讨论】:

  • 糟糕的标题。重写以总结您的具体技术问题。
  • 看起来确实是个错误,考虑到应用程序也会抛出错误,您已经验证了它。您提出的解决方案应该有效。可能只是人为错误,因为int 正常自动装箱?

标签: java android arrays


【解决方案1】:

您的诊断是正确的。给定两个重载 List.remove(int)List.remove(Object) 以及带有 int 参数的调用,Java 编译器将静态解析对第一个重载而不是第二个重载的调用1。但是这个上下文的语义需要第二个重载;即按值而不是按位置删除。

这是文档中的错误。通过正规渠道举报……


1 - 在JLS 15.12 中指定。这部分规范是复杂和技术性的,但要点是编译器首先查找匹配参数类型的重载严格;即没有装箱或拆箱。如果没有严格匹配,它只考虑非严格匹配。非正式地,int -> int 是比 int -> Object 更“接近”的匹配,其中涉及到Integer,然后将引用扩大到Object

【讨论】:

    猜你喜欢
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 2021-12-31
    • 2022-01-22
    • 2012-02-07
    • 2013-03-12
    相关资源
    最近更新 更多