2014-11-17 20 views
0

我有此代码,差()使用增强的for循环的方法和传统的for循环

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>我的指定者的理解(T [] a)方法,如果数组的大小小于列表中的元素,考虑到这一点,将使用数组指定的大小创建新数组,其中的元素将为空。我的数组应该看起来像这样[] = {null,null};

2>增强for循环和传统for循环之间的区别在于,您无法修改或删除增强for循环中的单个元素。

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

+0

你需要使用(一)',而不是在值传递指定者的'的返回值。在“参数”的文档中注明:“a - 如果该集合的元素足够大,将存储此集合的元素的数组;否则,为此分配了一个具有相同运行时类型的新数组”。 https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#toArray%28T[]%29 – msandiford

回答

1

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

也就是说,

  1. 如果你的列表的大小是2(和你一样 提供的方法数组的长度),如果你的数组长度或
  2. 3(相同 为你想要转换成数组的列表的大小),

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

至于NullPointerException,这是因为自动装箱从Integerint。也就是说,下面的代码就不会抛出NPE

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

,同时将下面的代码(因为它在你的情况一样):

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

至于为何编译器的拆箱与上面的增强for循环,想想看 - 数组的内容是boxed整数。您尝试将它们分配给primitive int引用(对于数组中的每个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 
} 
+0

1>什么是自动装箱?我知道自动装箱和拆箱。 2> autounboxing不会发生在传统的for循环中吗? 3>这个查询的另一个答案说我的数组a的大小是3.我在理解toArray()方法时错了吗? – Gpar

+0

'autounboxing'我的意思是''unboxing'''编译器'代表你做的。你做的2点正是我称之为“autounboxing”的原因 - 编译器为你做了这件事;在你展示的情况下你不这样做。而在3>我的意思是你的数组长度至少应该是'3',即'Integer [] a = new Integer [3]'。 – mystarrocks

+0

感谢@mystarrocks我的第一和第二点是清楚的。我的第三点基于JLS中的toArray()方法规范。根据哪个数组最新创建,因为集合和数组的大小不同,数组的大小比集合的大小小。这个新数组的大小将由集合指定大小还是由数组指定?即在我的程序中,大小为3或2? – Gpar

0
public <T> T[] toArray(T[] a) 

它需要数组作为参数的所有元素复制并返回该阵列。如果你的数组足够大,那么它会复制,否则在运行时将会分配相同的新数组用于此目的。在你的情况下,a的大小为2.因此创建了大小为3的新数组a,并将值复制到此新数组并返回。

第二件事,你正在印刷[我]而不是我。因为我包含元素值,所以打印我。

是这样的:

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