【问题标题】:java StringIndexOutOfBoundsException: -1java StringIndexOutOfBoundsException: -1
【发布时间】:2020-08-18 23:13:15
【问题描述】:

我正在尝试编写一个不和谐的机器人。 现在我有以下问题: 首先,我使用 String prefix = Setttings.readSetting("Prefix"); 加载前缀 然后我测试从不和谐收到的消息是否以前缀开头。 如果此测试通过,我将裁剪消息并提取命令本身并执行 方法的类中的方法。但这是我的问题: 当我的前缀长于 1 个字符时,我得到一个 StringIndexOutOfBoundsException。

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(Unknown Source)
    at listener.CommandManager.onGuildMessageReceived(CommandManager.java:38)
    at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:395)
    at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96)
    at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:64)
    at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:165)
    at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:97)
    at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:36)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:881)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:769)
    at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:748)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:919)
    at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385)
    at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276)
    at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996)
    at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755)
    at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108)
    at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64)
    at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)

这是类的代码:

package listener;

import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import tools.Settings;

import java.util.HashMap;
import java.util.Map;

import commands.*;

import assets.Command;

public class CommandManager extends ListenerAdapter {

    private static Map<String, Command> commands = new HashMap<String, Command>(); //here's where i store all the commands

    public static void init() { //In this method i put all the commands in the ArrayList. I call it on Program Start.

        commands.put("test", new TestCommand());

    }

    @Override
    public void onGuildMessageReceived(GuildMessageReceivedEvent event) {

        String prefix = Settings.readSetting("Prefix"); //Here i load the prefix.

        if(event.getMessage().getContentDisplay().startsWith(prefix)) {

            try {

                Command c = commands.get(event.getMessage().getContentDisplay().split(" ")[0].substring(prefix.length())); //Here occurs the error.

                if(c != null) {

                    c.execute(event);

                } else {

                    event.getChannel().sendMessage("Sorry, that command doesn't exist").queue();

                }

            } catch(Exception e) {

                e.printStackTrace();

            }
        }
    }

}

有谁知道错误和/或如何解决它? 谢谢。

【问题讨论】:

  • 这就是你的问题所在。你期望这会做什么? .split(" ")[0].substring(prefix.length()) 已经在空间上拆分字符串,为什么还要使用 substring?索引 0 将具有 prefix,索引 1 将具有第一个参数。
  • @ChristopherSchneider 什么?索引 0 将具有前缀和任何没有空格的连接。 "!hello world".split(" ") 将是 ["!hello", "world"] 其中 "!"将是前缀。
  • 怎么会有人知道这一点?问题中没有说明。带有prefix 的命令可以很容易地成为prefix arg0 arg1 ... argN

标签: java discord


【解决方案1】:

首先,关于具体异常:https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/

如果以某种方式访问​​数组(或 String),则通常会抛出 IndexOutOfBoundsException,导致参数索引超出数组的索引范围。

在您的情况下,会引发异常,因为您执行的字符串拆分可能不会在索引 0 处的数组中返回与 prefix.length() 一样长的值。或者换一种说法:如果getMessage返回的消息小于你的前缀长度怎么办?

实际例子:

// assume this input:
String prefix = "Hello";
String messageContentDisplay = "Hello Jack";

// your code does:
String[] segments = messageContentDisplay.split(" ");
String prefixInMessage = segments[0];
String subMessage = prefixInMessage.substring(prefix.length()); // This makes no sense.

我相信你真正想要的是削减前缀,它会像这样工作:

String displayContent = event.getMessage().getContentDisplay();
String[] segments = displayContent.split(" ");
if (segments.length > 1) {
    Command c = commands.get(displayContent.substring(segments[0].length));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多