我需要帮助理解错误消息

时间:2012-03-09 05:08:30

标签: java indexoutofboundsexception

这是一条错误消息,在我尝试显示我的程序结果时不断出现。

  Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
   at AddressBookIO.getEntriesString(AddressBookIO.java:38)
   at AddressBookEntryApp.main(AddressBookEntryApp.java:42)

我几乎可以肯定我的代码是正确的。除了显示我的结果之外,我的程序会执行它想要做的所有事情。 “”主“java.lang.ArrayIndexOutOfBoundsException:0”是令我困惑的部分。

下面是AddressBookIO.java和AddressBookEntryApp

的代码
import java.io.*;

public class AddressBookIO
{
private static File addressBookFile = new File("address_book.txt");
private static final String FIELD_SEP = "\t";
private static final int COL_WIDTH = 20;

// use this method to return a string that displays
// all entries in the address_book.txt file
public static String getEntriesString()
{
    BufferedReader in = null;
    try
    {
        checkFile();

        in = new BufferedReader(
             new FileReader(addressBookFile));

        // define the string and set a header
        String entriesString = "";
        entriesString = padWithSpaces("Name", COL_WIDTH)
            + padWithSpaces("Email", COL_WIDTH)
            + padWithSpaces("Phone", COL_WIDTH)
            + "\n";

        entriesString += padWithSpaces("------------------", COL_WIDTH)
            + padWithSpaces("------------------", COL_WIDTH)
            + padWithSpaces("------------------", COL_WIDTH)
            + "\n";

        // append each line in the file to the entriesString
        String line = in.readLine();
        while(line != null)
        {
            String[] columns = line.split(FIELD_SEP);
            String name = columns[0];
            String emailAddress = columns[1];
            String phoneNumber = columns[2];

            entriesString +=
                padWithSpaces(name, COL_WIDTH) +
                padWithSpaces(emailAddress, COL_WIDTH) +
                padWithSpaces(phoneNumber, COL_WIDTH) +
                "\n";

            line = in.readLine();
        }
        return entriesString;
    }
    catch(IOException ioe)
    {
        ioe.printStackTrace();
        return null;
    }
    finally
    {
        close(in);
    }
}

// use this method to append an address book entry
// to the end of the address_book.txt file
public static boolean saveEntry(AddressBookEntry entry)
{
    PrintWriter out = null;
    try
    {
        checkFile();

        // open output stream for appending
        out = new PrintWriter(
              new BufferedWriter(
              new FileWriter(addressBookFile, true)));

        // write all entry to the end of the file
        out.print(entry.getName() + FIELD_SEP);
        out.print(entry.getEmailAddress() + FIELD_SEP);
        out.print(entry.getPhoneNumber() + FIELD_SEP);
        out.println();
    }
    catch(IOException ioe)
    {
        ioe.printStackTrace();
        return false;
    }
    finally
    {
        close(out);
    }
    return true;
}

// a private method that creates a blank file if the file doesn't already exist
private static void checkFile() throws IOException
{
    // if the file doesn't exist, create it
    if (!addressBookFile.exists())
        addressBookFile.createNewFile();
}

// a private method that closes the I/O stream
private static void close(Closeable stream)
{
    try
    {
        if (stream != null)
            stream.close();
    }
    catch(IOException ioe)
    {
        ioe.printStackTrace();
    }
}

   // a private method that is used to set the width of a column
   private static String padWithSpaces(String s, int length)
{
    if (s.length() < length)
    {
        StringBuilder sb = new StringBuilder(s);
        while(sb.length() < length)
        {
            sb.append(" ");
        }
        return sb.toString();
    }
    else
    {
        return s.substring(0, length);
    }
  }
}

import java.util.Scanner;

public class AddressBookEntryApp
{
public static void main(String args[])
{
    // display a welcome message
    System.out.println("Welcome to the Address Book application");
    System.out.println();


    Scanner sc = new Scanner(System.in);


    int menuNumber = 0;
    while (menuNumber != 3)
    {
        // display menu
        System.out.println("1 - List entries");
        System.out.println("2 - Add entry");
        System.out.println("3 - Exit\n");

        // get input from user
        menuNumber = Validator.getIntWithinRange(sc, "Enter menu number: ", 0, 4);
        System.out.println();

        switch (menuNumber)
        {
            case 1:
            {
                String entriesString = AddressBookIO.getEntriesString();
                System.out.println(entriesString);
                break;
            }
            case 2:
            {
                // get data from user
                String name = Validator.getRequiredString(sc, "Enter name: ");
                String emailAddress = Validator.getRequiredString(sc, "Enter email address: ");
                String phoneNumber = Validator.getRequiredString(sc, "Enter phone number: ");

                // create AddressBookEntry object and fill with data
                AddressBookEntry entry = new AddressBookEntry();
                entry.setName(name);
                entry.setEmailAddress(emailAddress);
                entry.setPhoneNumber(phoneNumber);

                AddressBookIO.saveEntry(entry);

                System.out.println();
                System.out.println("This entry has been saved.\n");

                break;
            }
            case 3:
            {
                System.out.println("Goodbye.\n");
                break;
            }
        }
    }
}
}

6 个答案:

答案 0 :(得分:1)

异常意味着您正在访问超出数组大小的数组元素。因此,您需要提供代码的详细信息,以便让您了解问题的原因。

答案 1 :(得分:1)

表示已使用非法索引访问数组。索引为负数或大于或等于数组的大小。

根据您的错误日志.. AddressBookIO.java中第38行的代码抛出此异常。

可以在这里..

            String name = columns[0];
            String emailAddress = columns[1];
            String phoneNumber = columns[2];

如果0,1或2中没有元素..

答案 2 :(得分:1)

错误消息非常清楚:错误地访问了 no elements 的数组的第一个元素(索引0)。

  

线程“main”中的异常 java.lang.ArrayIndexOutOfBoundsException:[index is] 0

例如,这将抛出该异常:

int bad = (new int[0])[0]; // no elements :(

虽然以下是可以的:

int ok = (new int[1])[0];  // one element, can access it!

我怀疑是这样的:

String[] columns = line.split(FIELD_SEP); // empty array?
String name = columns[0];                 // KABOOM!

在任何情况下,请检查异常中报告行上的代码。

  

在AddressBookIO.getEntriesString( AddressBookIO.java:38

答案 3 :(得分:1)

'address_book.txt'中的空行可能是?

答案 4 :(得分:1)

您正在尝试访问空数组的第一个元素。它不存在,因此您从运行时获得异常。

您尝试访问的数组是split()方法的结果。如果您传递一串分隔符,则只会返回一个空数组:"\t"

因此,必须有一些行只包含它们之间没有任何内容的标签。

您应该考虑将正则表达式应用于每一行,而不是使用split()。这样,您可以同时验证行应用“捕获组”的格式,以便轻松提取每个字段的值,即使它们是空字符串。

Pattern p = Pattern.compile("([^\t]*)\t([^\t]*)\t([^\t]*)");
...
Matcher m = p.matcher(line);
if (!m.matches()) {
  /* The line is invalid; skip it or throw an exception. */
  ...
}
String name = m.group(1);
String emailAddress = m.group(2);
String phoneNumber = m.group(3);

答案 5 :(得分:0)

当您尝试访问索引时,会抛出

ArrayIndexOutOfBoundsException,该索引的大小超过指定数组的大小。

尝试改变这一点:

while(line != null)
{
    String[] columns = line.split(FIELD_SEP);
    String name = columns[0];
    String emailAddress = columns[1];
    String phoneNumber = columns[2];

    entriesString += padWithSpaces(name, COL_WIDTH) +
                       padWithSpaces(emailAddress, COL_WIDTH) +
                       padWithSpaces(phoneNumber, COL_WIDTH) +
                       "\n";

    line = in.readLine();
}

到此:

while(line != null)
{
    String[] columns = line.split(FIELD_SEP);
    if (columns.length > 2)
    {
        String name = columns[0];
        String emailAddress = columns[1];
        String phoneNumber = columns[2];

        entriesString += padWithSpaces(name, COL_WIDTH) +
                           padWithSpaces(emailAddress, COL_WIDTH) +
                           padWithSpaces(phoneNumber, COL_WIDTH) +
                           "\n";
    }
    line = in.readLine();
}