Java 数组索引

3
    class anEvent{ 
  String number;
  String dueTime;
 }



public static void main(String args[]) {
      int x = args.length / 2;
      int y = args.length;
      anEvent [] order = new anEvent [x];
      for(int i=0; i<x; i++){
       if(i==0){
        order[i].number = args[0]; //Line(#)
        order[i].dueTime = args[1];
       } else if ( i % 2 == 0){
       order[i].number = args[i];
       order[i].dueTime = args[i];
       } else if ( i % 2 != 0){
        order[i].number = args[i+1];
        order[i].dueTime = args[i+1];
       } else if ( i == x -1){
        order[i].number = args[x-1];
        order[i].dueTime = args[x-1];
       }

      }

Java提示上面片段的第#行存在空指针异常。

究竟出了什么问题呢?

注:我知道代码可以清理,但是第#行应该没有问题。


1
您没有指定行号? - djc
1
你尝试使用调试器逐步执行代码了吗?像这样的问题应该很容易通过调试器来识别。jdb 是可用的,而 Eclipse 和 NetBeans 都有集成的调试器... - Frank V
我在代码中注释了第#行(如果含糊不清,抱歉)。 我是Eclipse(和Java)的新手,我还没有学习过调试器。 - frantic
我认为 # 标记已经足够了。我希望更多的人在描述问题时发布代码(只需使用4个空格进行缩进即可完美呈现)。 - OscarRyz
5个回答

6

当创建一个数组时,所有的数组元素都是null。在你的情况下,你需要用new anEvent()实例填充该数组。


抱歉,但是:“授人以鱼不如授人以渔” :-) 我只是和你开玩笑,但我认为这很相关。 - Frank V
我写了一个 anEvent [] order = new anEvent [x],这不够吗? - frantic
1
@frantic:不,这还不够;正如Chris所写,它创建了一个仅包含null的数组。 - Michael Borgwardt
1
@frantic:不,这还不够。你只是分配了一个具有x个组件的数组。此时数组中的所有组件都为null。你还应该分配anEvent类的实例并将它们分配到数组组件中。 - Lauri
@Frank:我同意,通常对于有作业问题的人,我会尽力避免直接给出答案。但是你可以从原帖作者的回复中看到,他们甚至不知道从哪里开始。让他们尝试使用调试器来查找显然是没有任何用处的。 :-( - C. K. Young

1

将你的for循环的第一行编写为:

order[i] = new anEvent();

目前,你没有对数组进行任何初始化(它们都是null),因此当你尝试访问字段时会出现异常。


1

由于您提到它“可以清理”,所以我冒昧这样做:

public class Thing {
    private String number;
    private String dueTime;

    public Thing(String number, String dueTime) {
        this.number = number;
        this.dueTime = dueTime;
    }

    public static void main(String args[]) {
        int x = args.length / 2;
        Thing[] order = new Thing[x];
        for (int i = 0; i < x; i++) {
            if (i == 0) {
                order[i] = new Thing(args[0], args[1]);
            } else if (i % 2 == 0) {
                order[i] = new Thing(args[i], args[i]);
            } else if (i % 2 != 0) {
                order[i] = new Thing(args[i + 1], args[i + 1]);
            }
        }
    }
}

"

“anEvent”不符合Java标准的大写驼峰命名法,因此我将其重命名。 “Thing”并不特别有意义,但在这里没有太多可用的信息。最终的else if子句永远无法到达,因为i%2要么要么不是等于零,所以我将其删除。当然,我正在创建新的Things,这避免了空值的问题。享受吧。

"

1

NullPointerException 意味着您尝试向某个值或执行方法的对象添加一个 null 值。

在 Java 中,对象引用可以被分配为...好吧,对象null

当它们被分配为 null 时,就会抛出此异常:

Object o = null;
o.toString(); // <- NullPointerException ( think of null.toString() )

数组也是对象。当您创建一个具有大小的数组时,数组中的所有“盒子”都包含null作为引用。

因此:

Object[] array = new Object[10];

创建类似于以下内容的东西:
 [null,null,null,null,null,null,null,null,null,null]

这就是为什么当你执行以下命令时:

array[0].toString(); // or  order[i].number in your specific example... 

你会得到那个异常,因为效果与以下情况完全相同:

null.toString();  // or null.number  <-- NullPointerException.

为了解决这个问题,你需要将一个有效的对象引用分配到数组的那个位置:
for(int i=0; i<x; i++){
    order[i] = new anEvent();
    ...
    ...

我希望这可以帮助到您。

最后注意事项。在Java中,类名以大写字母开头,因此您的类名应该是:

class AnEvent {
....

最后,大多数Java源代码都使用4个空格进行缩进。


0

你还没有创建任何anEvent实例,定义一个数组(order []),你没有为它创建默认值。

而且对于你的情况,还有更简单的数组:

List events = new ArrayList(x);
for(int i=0; i<y; i+=2){
  anEvent event = new anEvent();
  anEvent.number = args[i];
  anEvent.dueTime = args[i+1];
  events.add(event);
}
anEvent[] order = events.toArray();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接