【问题标题】:How can I stop this out of bounds exception in Java如何在 Java 中阻止这种越界异常
【发布时间】:2016-03-12 10:34:12
【问题描述】:

您好,我想知道如何编写一个 try and catch 块来阻止出现以下错误。

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

我有这个方法,它接受一个句子并将其拆分为一个 ArrayList。然后我使用它将值存储到哈希图中,其中索引 1 是键,后面的单词成为值。我使用下面的方法将用户输入拆分成一个数组。

私人扫描仪阅读器;

    /**
     * Create a new InputReader that reads text from the text terminal.
     */
    public InputReader()
    {
        reader = new Scanner(System.in);
    }

    public ArrayList<String> getInput() 
    {
        System.out.print("> ");                // print prompt
        String inputLine = reader.nextLine().trim().toLowerCase();

        String[] wordArray = inputLine.split(" ");  // split at spaces

        // add words from array into ArrayList
        ArrayList<String> words = new ArrayList<String>();
        for(String word : wordArray) {
            words.add(word);
        }
        return words;
    }

}

下面的方法使用上面的类来检测用户输入。因此,当用户输入 write 时,他们可以写入 hashmap,但是如果他们在输入键和值之前按回车键,我会得到越界异常。那么我该如何重写下面的方法来避免这种情况呢?

 public void start()
    {

        boolean finished = false;


            printWelcome();
            while(!finished) {
                ArrayList<String> input = reader.getInput();

                if(input.contains("shutdown")) {
                    finished = true;
                }

                if (input.contains("load")) {
                    System.out.println();
                    instruct.readAndFill();
                    System.out.println();
                }            

                if (input.contains("write")) {
                    String key = input.get(1);
                    String value = "";
                    for(int i=2; i<input.size(); i++) {
                        value = value + " " + input.get(i);
                    }
                    instruct.mapWrite(key, value);
                }
            } 
            instructorGoodBye();
        }

对不起,如果我不够清楚,或者我的代码没有达到标准,我现在才学习 java 大约 2 个月。

【问题讨论】:

  • 大小为 1 的容器(数组、列表等)只有一个元素,索引为零。尝试使用索引 1 会出现越界错误。请使用调试器(Eclipse、NetBeans、Idea)来单步调试您的代码并在出现异常时停止,这样您就可以看到发生了什么。如果您不知道如何执行此操作,请在网络上查找教程并在做任何其他事情之前学习。使用调试器是学习编码的基础,除非您这样做,否则您将受到严重限制。
  • 您的问题可能出在这一行:String key = input.get(1);,要成功,您的列表中需要包含两个元素,而且看起来只有一个。
  • @nickb HI Nick 基本上 if (input.contains("write")) 被视为第一个元素,基本上如果用户在一行上输入 write key value 就可以了,但如果他们点击写入后返回,然后发生错误。我不知道如何重写它以避免这种情况。
  • 运行时异常如IndexOutOfBoundsExceptionNullPointerException 表示程序逻辑不正确。不要尝试使用try...catch 修复它们。相反,更正程序,使其不提供错误的索引或无效的参数等。
  • @JimGarrison 感谢 Bluej 确实带有调试器,我现在会看看它。

标签: java hashmap indexoutofboundsexception bluej


【解决方案1】:

基本上,如果用户在一行上输入 write key value 就可以了,但如果他们在 write 后点击 return,则会发生错误。

所以,基本上你缺少的是错误检查。您的程序正在接受用户的输入,并假设它是有效的。 这总是一个坏主意

相反,您应该验证您从用户那里获得的信息。对于“写入”块,您可以这样做的一种方法是确保您期望的元素确实存在。

首先,我将重写你的循环如下:

while(!finished) {
    List<String> input = reader.getInput();
    if(input.size() == 0) {
        throw new IllegalArgumentException("Must specify command, one of 'shutdown', 'load', 'write'");
    }

    final String command = input.remove(0).toLowerCase();
    // TODO: Make sure command is one of the valid commands!

注意变化:

  1. 分配给List 而不是ArrayList 只是一个很好的常规做法。
  2. 检查输入以确保它有多个元素
  3. 取第一个元素,因为我们不想做List.contains()。考虑输入garbage garbage garbage write,显然我们不希望它调用“write”命令,它应该被视为无效输入。

最后,我们用它来重写执行命令的条件:

if(command.equals("write")) {
    // Make sure the user put the right stuff in here
    // Since we removed the command from the input already, just make sure what is left is 
    if(input.size() <= 1) {
        throw new IllegalArgumentException("Must specify correct data");
    }
    String key = input.remove(0);
    String value = String.join(" ", input); // Java 8
    instruct.mapWrite(key, value);
}

【讨论】:

  • 非常感谢,在我实施之前,我将确保我完全理解这些更改以及代码。
  • 您好,如果用户按回车,系统仍然会崩溃,我不希望系统在用户按回车时崩溃,而是告诉他们出了什么问题,让他们再试一次。
  • @user5647516 - 这是您必须提高调试技能的地方。问问自己,为什么会崩溃?使用堆栈跟踪对您有利。你知道按回车是一个无效的输入,所以你需要为那个条件写一个检查,如果检查成功,你告诉用户他们做错了什么。
【解决方案2】:

您收到以下部分代码的错误..

if (input.contains("write")) {
                    String key = input.get(1);// here is the problem..
                    String value = "";
                    for(int i=2; i<input.size(); i++) {
                        value = value + " " + input.get(i);
                    }
                    instruct.mapWrite(key, value);
                } 

在此代码的第 2 行 sn-p. 您正在使用索引访问一个值。现在想象一下,您只需在控制台中输入一个单词。因此,您将从 getInput() 方法获得的数组列表的大小为 1。所以.. 在数组列表中,单词将被放置在第 0 个位置。(即第一个位置)但您正在访问第二个位置的值.. 那就是给你一个超出债券异常的索引..

【讨论】:

  • 谢谢@kaushik 重写这个的最好方法是什么?我应该尝试一下吗?
  • 使用 try catch 块将无效。你可以使用检查类型的东西。如果列表的大小为 1,那么您可以打印错误消息 ..
【解决方案3】:

基本上,修复比抛出新异常和使用 try 和 catch 块更简单。我所要做的就是稍微改变逻辑,然后使用 if else 语句。

  if (input.contains("write")) {    
                    if(input.size() >=2) {

                        String key = input.get(1);                   
                        String value = "";
                        for(int i=2; i<input.size(); i++) {
                            value = value + " " + input.get(i);
                        }
                        mapWrite(key, value);
                    } else {
                        System.out.println("Please type in the key & value after write all on line");
                    }

                }

到目前为止,我从 java 中学到的知识是,最好的解决方案通常总是最简单的。感谢所有的帮助,所有评论并试图帮助我的人基本上都帮助我提出了这个想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-08
    • 2018-11-19
    • 2013-03-30
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多