为什么在循环中分配数组中的引用后得到NullPointerExceptions?

时间:2011-03-31 15:18:14

标签: java

为什么这不起作用:

//...
Integer[] array=new Integer[5];
for(Integer x: array){x=-1;}
printArray(array);
//...

// the print function is the following
public static String printArray(Object[] array){
    String str="";
    for(Object obj : array){
         str+=obj.toString()+" ,";
    }
    System.out.println(str);
}

我在printArray函数的for-each语句中得到了NullPointerException,为什么?

8 个答案:

答案 0 :(得分:9)

因为您从未使用任何值初始化数组,所以它只包含一堆null个。您需要先给它赋值,然后才能在它们上面调用.toString()

例如:

Integer[] array = new Integer[5] { 1, 2, 3, 4, 5 };

您的初始循环(x = -1}不会更改数组,而是更改循环中的瞬态对象x。就像这样:

for (int i = 0; i < array.length; i++) {
    Integer j = array[i];
    j = -1;
}

相反,如果要使用循环初始化,请执行此操作:

for (int i = 0; i < array.length; i++) {
    array[i] = -1;
}

答案 1 :(得分:2)

Integer[] array=new Integer[5];
for(Integer x: array){x=-1;} 

上面的代码不会更新数组。如果要更新它,则需要为数组元素赋值,如下所示。

for( int i = 0; i < array.length; i++ )
  array[ i ] =-1;

第一个代码段没有做任何有用的原因是Java只是按值传递。当您创建局部变量x并将数组元素指定为其值(就像在代码中一样)时,它将包含对(Integer对象)的引用,但不是它在阵列中的位置。当您更改x的值时,只需将x指向其他对象。

答案 2 :(得分:1)

对局部变量x进行赋值,它不会自动传播到数组变量。 试试这个:

for(int i = 0; i < array.length; i++) {
     array[i] = -1;
}

答案 3 :(得分:1)

当你执行x = -1时,您将为变量x分配一个新实例,而不是更改数组中对象的值。因此,您的阵列实际上是未初始化的。

答案 4 :(得分:1)

for(Integer x: array){x=-1;}不会初始化数组,它只是将临时变量x设置为-1五次。

答案 5 :(得分:1)

  

这个java代码出了什么问题

既然你问过......我会

 int[] array=new int[5];
 Arrays.fill(array);
 System.out.println(Arrays.toString(array));
  • 对整数类型使用int。
  • 使用内置Arrays方法填充和toString数组。
  • 在字符串
  • 上使用StringBuilder而不是+ =
  • printString打印一个字符串或printArray打印数组或返回一个字符串,因为您可能会忽略结果,就像您在示例中所做的那样。如果它返回一个String,则将其命名为toString()或asString()。
  • 在参数上使用varargs。
  • 不要调用object.toString(),因为为您调用toString()。除了更短,null不会抛出异常!!
  • 使用“,”而不是“,”
  • 删除最后一个“,”。

但是说你想写自己的printArray ......

// the print function is the following
public static void printArray(Object... objects) {
    StringBuilder str = new StringBuilder();
    for (Object obj : objects)
        str.append(obj).append(", ");
    if (str.length() > 1) str.delete(str.length() - 2, str.length());
    System.out.println(str);
}

public static void printArray(int... ints) {
    StringBuilder str = new StringBuilder();
    for (int i : array)
        str.append(i).append(", ");
    if (str.length() > 1) str.delete(str.length() - 2, str.length());
    System.out.println(str);
}

答案 6 :(得分:0)

分配给x不会写入数组。你必须做这样的事情

for(int i = 0; i < array.length; i++) {
    array[i] = -1;
}

答案 7 :(得分:0)

您从未初始化vales表单数组。

1

Integer [] array = new Integer [5];

这里你在内存中保留了五个整数对象的空间,假设有五个具有唯一地址的盒子;

  1. for(Integer x:array){       x = -1;     }

  2. 这里的事情要复杂得多,你实际做的是这个

    2.1为称为x的Integer对象分配内存(另一个框) 2.2你从表中指定(放置)值*(为空); 2.3你给它分配值-1 **; 2.4从步骤2.2开始重复,直到保留的内存未完成(五次)。

    所以主要问题是你永远不会将值分配到数组中,而不是将任何内容插入到框中。

    要解决这种情况,您应该为每个框分配一个值,然后您可以根据需要使用它们。

    for(int i=0; i< array.length; i++) {
      array[i] = new Integer("-1");
    }
    

    现在在每个循环中,我们指的是框,我们存储值;

    *按值我的意思是那些盒子的地址,因为你使用的是reference type

    **您还在内存中创建并装箱,并为此-1分配一个地址(即从缓存中检索)。并且编译器会将x=-1;更改为x = Integer.valueOf(-1);

    接下来是方法printArray(Object [] array):

    你应该记住,因为使用了大量内存,所以操作非常昂贵。你在那里做的是concatenation,通常不受欢迎。

    接下来出现的问题是分工你已经调用了方法print数组,但是你也在那里创建了实际上将被打印的字符串。好的方法是将这些操作分开。

    public static String arrayToString (Object... array) { //... varags  
    
      if(array == null) {
        return "null"; //If is null we just return String null.
      }
    
      int max = array.length - 1;
    
      if(max == -1) { //We check that array is empty length
       return "[]";
      }
    
      StringBuilder sb = new StringBuilder("[");
    
      int i = 0;
    
      while(i <= max) {
    
        sb.append(String.valueOf(array[i])); //String.valueOf method is a helper, in situation when in array are null we will get from that method "null" if we wrote array[i].toString; in case when in box i there was no element set we would get null pointer exception. That was your real last problem. But when you are using string builder this is not necessary.
    
        if(i < max) {
          sb.append(", ");
        }
    
        i++;
      }
    
      return sb.append(']').toString();
    
    }
    
      public static String print(String str) {
         System.out.println(str);
      }
    

    聚苯乙烯。

    为了更简单的方法,您可以使用:

    Arrays.fill(array,new Integer(-1));
    Arrays.toString(arrays);