【问题标题】:Null Pointer that makes no sense to me?对我来说没有意义的空指针?
【发布时间】:2013-09-22 00:16:53
【问题描述】:

我目前正在开发一个程序,任何时候我调用 Products[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());

【问题讨论】:

  • readLines() 返回什么值?
  • 我强烈建议你学习使用调试器。
  • readLines() 返回一个 int 表示文件中有多少行
  • 大卫我使用调试器说我在该数组中调用 [2] 或 [0] 的任何位置都有一个空指针。我不明白的是我如何从计算 Tax() 和 calculateItemTotal() 的数组中获得两个输出,但是在调用 Products[1].getItemTotal 时我只得到一个,而当我尝试调用 2 时,我得到一个空指针错误跨度>
  • @user2786754 通过外部 for 循环进行调试。执行是否进入带有continueif 语句?

标签: java arrays nullpointerexception


【解决方案1】:

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

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

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

products 也应该以小写开头以遵循 Java 约定。类型以大写字母开头,参数和变量以小写字母开头。并非所有 Java 编码约定都是完美的——但这个非常有用。

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

一般你应该建立列表(ArrayList)。 Map(HashMap、LinkedHashMap、TreeMap)和Set(HashSet)也很有用。


第二个错误:正如 Bohemian 所说:在 data[] 中,您混淆了所有行列表的概念,而 data[] 是从单行解析/拆分的标记。

“数据”通常是一个无意义的术语。使用有意义的术语/名称,您的程序中出现错误的可能性要小得多。

您可能应该只使用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;
    }

当您为问题提供示例输入时,请将其编辑到问题的正文中,以便阅读。将它放在无法正确读取的 cmets 中,只是在浪费试图帮助您的人的时间。

【讨论】:

  • 是的,它应该这样做,因为输入如下输入 2:1 盒进口巧克力 10.00 1 瓶进口香水 47.50
  • 那么,即使 2 个输出显示跳过第一行使数组中的 0 空间和数组中的 2 空间都为空,这是如何做到的呢?并且数组中的 3 个空间超出范围?
【解决方案2】:

错误警报:您正在覆盖data

String [] data = new String[numberOfLines];

然后在循环中:

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

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

【讨论】:

  • 正确,这里有大错误。看来data 应该用作单行中的标记,但最初声明 & 在某一点(“跳过输入”检查)由行号索引。单行应该是tokens一般来说,变量不应该在需要之前声明/调整大小。
【解决方案3】:

您需要为行号和新产品对象使用不同的索引。如果您有 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
}

【讨论】:

  • jarmod 我仍然在任何大于 0 的索引处获得空指针,但是您的解决方案确实将可用产品变成了 0 的索引。
  • 您是否在创建产品[1](及更高版本)之前访问它们?如果是这样,它们将为 null 并导致 nullpointerexception。在执行 Products[prod_count] = new Product() 其中 prod_count 为 1 之前,您无法访问 Products[1]。
猜你喜欢
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
相关资源
最近更新 更多