【问题标题】:ArrayIndexOutOfBoundsException generated when br.readLine() = ","br.readLine() = "," 时产生 ArrayIndexOutOfBoundsException
【发布时间】:2016-11-11 12:25:02
【问题描述】:

下面的代码有几个函数允许诸如将数据写入文档、读取文档并将数据放入数组中以供稍后的JTable 使用。

package tabletest.populatetable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class GetData {
    DataClass[] data = new DataClass[500];
    int nextPosition = 0;

    public GetData() {
        readData();
    }

    public void writeData()
    {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(new File("resources/tabledata.txt")));

            for(int i=0; i < nextPosition; i++) {
                bw.write(data[i].toString());
                bw.newLine();
            }

            bw.close();
        } catch(Exception e) {
            System.out.println("Invalid Data input");
        }
    }

    public void readData()
    {
        try {
            BufferedReader br = new BufferedReader(new FileReader(new File("resources/tabledata.txt")));
            String nextData = br.readLine();
            String[] arrayStringData;

            while (nextData != null) {

                try {
                    arrayStringData = nextData.split(",");
                } catch(NullPointerException nPE) {
                    arrayStringData = new String[] {" ", " "};
                }

                for(int i = 0; i < arrayStringData.length - 1; i++) {
                    if(arrayStringData[i] == null || arrayStringData[i] == "") {
                        arrayStringData[i] = " ";
                    }
                }

                DataClass getData = new DataClass();
                getData.col1 = arrayStringData[0].trim();
                getData.col2 = arrayStringData[1].trim();
                data[nextPosition] = getData;
                nextPosition++;
                nextData = br.readLine();
            }

            br.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public String[][] dataInTableForm() {
        final int colCount = 2;
        String[][] temp = new String[nextPosition][colCount];

        for(int i = 0; i < nextPosition; i++) {
            temp[i][0] = data[i].col1;
            temp[i][1] = data[i].col2;
        }

        return temp;
    }

    private class DataClass {
        String col1;
        String col2;

        public String toString() {
            return col1 + ", " + col2;
        }
    }
}

它正在阅读的文档 resources/tabledata.txt 有 12 行长,看起来像这样。

asfias, adsnj
aw,aerfae
aw,aewaa
,tre
asfd, 
okfas,af
e,ds
sw,f
,
asfias, adsnj
aw,aerfae
aw,aewaa

问题出在文本文档的第 9 行。这就是它本身只是一个, 的地方。当逗号之前或之后有东西时,这似乎工作正常,我通过删除该行来检查它是否确实是引起问题的逗号。

当我查看控制台时,我发现问题出在 ArrayIndexOutOfBoundsException 并且堆栈跟踪如下。

java.lang.ArrayIndexOutOfBoundsException: 0
    at tabletest.populatetable.GetData.readData(GetData.java:55)
    at tabletest.populatetable.GetData.<init>(GetData.java:14)
    at tabletest.Table.createTablePanel(Table.java:76)
    at tabletest.Table.createPanels(Table.java:34)
    at tabletest.Table.runGUI(Table.java:24)
    at tabletest.Table.main(Table.java:150)

代码第55行是getData.col1 = arrayStringData[0].trim();

正如您在代码中看到的那样,我尝试了几件事来防止这种情况发生,但我没有运气。我还尝试从行尾删除.trim();但是,会出现完全相同的问题。

对于解决此问题的任何帮助,我将不胜感激。

【问题讨论】:

  • if (arrayStringData.length &gt; 0)环绕54-58线。

标签: java swing indexoutofboundsexception


【解决方案1】:

split(String regex) 的 Javadoc 说:

此方法的工作方式就像通过使用给定表达式和零限制参数调用两个参数 split 方法一样。 因此结果数组中不包含尾随的空字符串。

所以,",".split(",") 将返回一个空数组,即new String[0]

如果您想保留尾随空字符串,请使用",".split(",", -1),它将返回new String[] { "", "" }

【讨论】:

    【解决方案2】:

    split 函数将删除 "," 分隔符并返回一个空数组。

    如果nextData 数组为空,您的 try-catch 块将捕获空指针异常,而不是在输出数组为空的情况下。

    for 循环仅在输出数组包含空字符串(它不包含)时才有效。

    【讨论】:

    • split() 确实从不返回分隔符,即“将其删除”,但这并不能解释为什么它返回空数组,而不是预期的两个空字符串的数组。
    【解决方案3】:

    String.split 将分隔符从结果数组中拉出。因此,对于只有“,”的字符串,您的数组长度为 0(索引 0 处的元素不存在)。

    你需要做的是检查长度是否大于0。你可以在尝试访问arrayStringData之前在if语句中使用代码arrayStringData.length &gt; 0来做到这一点

    【讨论】:

    • 应该 for 循环或 try catch 块不能阻止这种情况吗?
    • @Dan 是的,它确实捕获了它,但你没有对异常做任何事情。您只是在打印堆栈跟踪。您需要做的是在尝试访问之前检查长度是否大于0:arrayStringData.length &gt; 0
    • 当然是“yanks”分隔符,但这不是结果是空数组而不是两个空字符串的数组的原因。 ",""&lt;emptyString&gt;,&lt;emptyString&gt;",因此将该字符串读取为逗号分隔值,这意味着两个空字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    相关资源
    最近更新 更多