0

我有这个代码,

class Test
{
    public static void main(String args[])
    {
        ArrayList<Integer> al=new ArrayList<>();
        al.add(1);
        al.add(2);
        al.add(3);
        Integer a[]=new Integer[2];
        al.toArray(a);
        for(int i:a)
        System.out.println(i);
        /*for(int i=0;i<a.length;i++)
        System.out.println(a[i]);*/

    }
}

上面的代码抛出 NullPointerException 但如果我尝试关闭注释部分,并为循环增强注释,它将打印 null 2 次。打印 a.length 打印 2。将整数数组大小设置为 3 将打印 123。

如果我错了,现在纠正我:

1> 我对 toArray(T[] a) 方法的理解是,如果数组的大小小于列表中的元素,则将创建具有数组指定大小的新数组,并且其中的元素将为空,考虑到这一点. 我的数组应该看起来像这样 a[]={null,null};

2> 增强型for循环与传统for循环的区别在于增强型for循环中不能修改或删除单个元素。

但是,为什么这个程序会有所不同呢?我只是打印它们,为什么增强for循环不打印null并抛出NullPointerException?

4

2 回答 2

1

toArray(a)方法返回转换后的数组,这就是您应该使用的;它没有使用你的数组,因为它不够大。

那是,

  1. 如果您的列表的大小是2(与您提供该方法的数组的长度相同)或
  2. 如果您的数组长度是3(与要转换为数组的列表的大小相同),

您将不需要返回的数组;因此,您的for循环会打印出您想要的内容。

至于NullPointerException,这是因为它从Integer到的自动拆箱int。也就是说,以下代码不会抛出NPE:

for(Integer i : a)
{
  System.out.println(i);
}

而以下代码将(就像您的情况一样):

for(int i : a)
{
  System.out.println(i);
}

至于为什么编译器使用上述增强的 for 循环进行拆箱,请考虑一下 - 数组的内容是boxed整数。您尝试将它们分配给一个primitiveint 引用(将其读取为数组中的每个 int),因此唯一的方法是取消装箱对象。

for(int i : a)
{
  System.out.println(a[i]);
}

翻译成

for(int i = 0; i < a.length; i++)
{
  System.out.println((int) a[i]);  // a[i] is null here, so casting causing an NPE
}

或者更准确地说,

for(int i = 0; i < a.length; i++)
{
  System.out.println(a[i].intValue()); // a[i] is null here, causing an NPE
}
于 2014-11-17T00:30:56.897 回答
0
public <T> T[] toArray(T[] a)

它将数组作为参数来复制所有元素并返回该数组。如果您的数组足够大,那么它将在运行时复制到另一个相同的新数组上以用于此目的。在您的情况下, a 的大小为 2。因此在运行时创建大小为 3 的新数组 a ,并将值复制到该新数组并返回。

第二件事是打印 a[i] 而不是 i。因为 i 包含元素值,所以打印 i。

像这样的东西:

public static void main(String args[])
{
    ArrayList<Integer> al=new ArrayList<>();
    al.add(1);
    al.add(2);
    al.add(3);
    Integer a[]=new Integer[2];
    a=al.toArray(a);
    for(Integer i:a) //or for(int i:a)
    System.out.println(i);
}
于 2014-11-17T01:07:28.857 回答