空指针对我没有意义?

时间:2013-09-22 00:16:53

标签: java arrays nullpointerexception

我目前正在处理一个程序,任何时候我称产品[1]没有空指针错误,但是,当我调用Products [0]或Products [2]时,我得到一个空指针错误。然而,我仍然得到2个不同的输出,几乎就像阵列中有[0]和1或1和2。这是我的代码

    FileReader file = new FileReader(location);
    BufferedReader reader = new BufferedReader(file);

    int numberOfLines = readLines();
    String [] data = new String[numberOfLines];
    Products = new Product[numberOfLines];
    calc = new Calculator();

    int prod_count = 0;
    for(int i = 0; i < numberOfLines; i++)
    {
        data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
        if(data[i].contains("input"))
        {
            continue;
        }
        Products[prod_count] = new Product();
        Products[prod_count].setName(data[1]);
        System.out.println(Products[prod_count].getName());
        BigDecimal price = new BigDecimal(data[2]);
        Products[prod_count].setPrice(price);


        for(String dataSt : data)
        {

            if(dataSt.toLowerCase().contains("imported"))
        {
                Products[prod_count].setImported(true);
        }
            else{
                Products[prod_count].setImported(false);
            }

        }



        calc.calculateTax(Products[prod_count]);    
        calc.calculateItemTotal(Products[prod_count]);
        prod_count++;

这是输出:

imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62

此图片适用System.out.println(Products[1].getProductTotal());

这将成为空指针System.out.println(Products[2].getProductTotal());

这也成为空指针System.out.println(Products[0].getProductTotal());

3 个答案:

答案 0 :(得分:3)

您正在跳过包含“输入”的行。

if(data[i].contains("input")) {
    continue;          // Products[i] will be null
}

可能最好将products设为ArrayList,并仅向其中添加有意义的行。

products也应该以小写字母开头,以遵循Java惯例。类型以大写,参数&amp;变量以小写开头。并非所有Java编码约定都是完美的 - 但这一点非常有用。

代码结构正常,但是数组不是一个非常灵活的类型来构建程序逻辑(因为长度必须预先确定,跳过需要你跟踪索引,它无法跟踪你建造它的大小。)

通常你应该构建List(ArrayList)。 Map(HashMap,LinkedHashMap,TreeMap)和Set(HashSet)也很有用。


第二个错误:波希米亚人说:在data[]中,你混淆了所有行列表的概念,data[]是从一行解析/拆分的令牌。

“数据”通常是无意义的术语。使用有意义的术语/名称&amp;你的程序不太可能有bug。

你应该只使用tokens作为行标记,而不是在需要之前/之前声明它,而不是尝试按行索引 - 因为,很简单,应该完全没有必要

for(int i = 0; i < numberOfLines; i++) {
    // we shouldn't need data[] for all lines,  and we weren't using it as such.
    String line = reader.readLine();
    String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
    //
    if (tokens[0].equals("input")) {        // unclear which you actually mean.
    /* if (line.contains("input")) { */    
        continue;
    }

当您提供问题的示例输入时,请将其编辑到问题正文中,以使其可读。将它放在评论中,无法正确阅读,只是浪费了那些试图帮助你的人的时间。

答案 1 :(得分:2)

错误提醒:您正在覆盖data

String [] data = new String[numberOfLines];

然后在循环中:

data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");

所以谁知道它有多大 - 取决于拆分的成功 - 但是你的代码依赖于numberOfLines长。

答案 2 :(得分:0)

您需要为行号和新产品对象使用不同的索引。如果您有20行,但其中5行是“输入”,那么您只有15个新产品对象。

例如:

int prod_count = 0;

for (int i = 0; i < numberOfLines; i++)
{
        data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
        if (data[i].contains("input"))
        {
            continue;
        }
        Products[prod_count] = new Product();
        Products[prod_count].setName(data[1]);
        // etc.
        prod_count++; // last thing to do
}