3499 个元素后的 Java 数组空指针

Posted

技术标签:

【中文标题】3499 个元素后的 Java 数组空指针【英文标题】:Java array null pointer after 3499 elements 【发布时间】:2013-09-23 09:44:59 【问题描述】:

我有一段代码用于扫描大量数字(作为整数)并将它们存储到场景对象中。但是,在我到达第 3499 个对象(它打印第 3498 个 J)之后,它会因空指针而崩溃。我寻找了最大数组大小,但除了 2^32-5 在互联网上找不到任何东西,但我什至没有接近这个限制。

        in1scan = new Scanner(in1);
        in2scan = new Scanner(in2);
        scenario[] ret= new scenario[9999];
        int j=0;

        while (in1scan.hasNext())
            String[] input=(in1scan.next().split(",", 16));
                    ret[j]=new scenario();
            for (int i=0; i<16;i++)

                ret[j].input[i]=Integer.parseInt((input[i]));   
            
            j++;
        

        j=0;
        while (in2scan.hasNext())
            ret[j].correct=Integer.parseInt(in2scan.next()); //here things go wrong
            j++;
            System.out.println(j);
        

有人知道怎么回事吗?是的,我知道我可以使用 nextInt 而不是当前接受数字的迂回方式,但我将添加一些需要以这种方式处理的额外功能。

【问题讨论】:

我认为您的第二个输入(由in2scan 扫描的那个)可能比您的第一个大。可以肯定的是,您必须发布一个堆栈跟踪。 我们需要一个堆栈跟踪来准确地查看它失败的地方。它总是有帮助的。 您的correct 是否比input 多?因为您只是在第一个循环中创建一个新的场景对象,所以如果您有更多 correct,您将无法访问 ret[j].correct 在说这里出问题的那一行我得到一个 java.lang.NullPointerException。 问题:for (int i=0; i&lt;16;i++) 这一行是怎么回事?在我看来,您为当前 j 创建了 16 次新的场景对象。 【参考方案1】:

你已经“用完了”ret。

在这部分代码中,您将创建ret 的第一个in1scan.size() 元素

    while (in1scan.hasNext())
        String[] input=(in1scan.next().split(",", 16));
        for (int i=0; i<16;i++)
            ret[j]=new scenario();
            ret[j].input[i]=Integer.parseInt((input[i]));   
        
        j++;
    

这里使用ret 的第一个in2scan.size() 元素。如果in2scan.size() &gt; in1scan.size()ret[j] 将为空,因此无法调用.correct

    j=0;
    while (in2scan.hasNext())
        ret[j].correct=Integer.parseInt(in2scan.next()); //here things go wrong
        j++;
        System.out.println(j);
    

在调试器中单步执行将(希望)确认这一点

【讨论】:

它确实看起来像 ret[j] 不知何故用完了,而它不应该(如果一切顺利的话 ret[j] 应该已经足够大了)。 @Thijser 你能保证在某处 in1scan.size()==in2scan.size()?【参考方案2】:

堆栈跟踪告诉你异常被抛出

        ret[j].correct=Integer.parseInt(in2scan.next()); //here things go wrong

所以retret[j]in2scan 为空。

要找出它是什么,为 NullPointerException 设置一个异常断点,并在调试模式下运行程序。这将在抛出异常时暂停执行,从而允许您检查当时的程序状态。

【讨论】:

在非第一个循环和 in2scan.hasNext() 为真时只有一个可能。 ret[j] 必须为空 可能。但是什么是 j,为什么 ret[j] 为空?查看调试器中的局部变量可能会产生有价值的线索。当程序太复杂而无法通过查看代码来找到错误时,这也是一种很好的做法...... 当然正确,你不会发现我反对使用调试器的任何论据【参考方案3】:

i&lt;16 应该是 i &lt; input.length。因为 `split(.., 16) 只指定了一个最大值。

【讨论】:

好点,我也是这么想的,除非这个被分割的输入总是有 16 个长度。 必须是输入数据中的错误,即使“总是”有 16 个值,第 34999 行上的值之一也可能包含 EBCDIC 换行符 (NEL) 并被部分读取,或者其他.那么更高的元素为空。

以上是关于3499 个元素后的 Java 数组空指针的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的java字符串数组空指针异常[重复]

Java常见的错误种类

Java常见异常

Java常见异常总结

常见java异常

java常见异常总结