英文:
java StringIndexOutOfBoundsException: -1
问题
我正在尝试编写一个 Discord 机器人。
现在我遇到了以下问题:
首先,我使用字符串前缀加载设置,代码如下:String prefix = Setttings.readSetting("Prefix");
然后,我测试从 Discord 收到的消息是否以前缀开头。
如果测试通过,我会截取消息并提取命令本身,然后执行该命令所在类的方法。但是这是我的问题:
当我的前缀长度大于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>(); // 这里存储所有命令
public static void init() { // 在这个方法中,我将所有命令放入 ArrayList 中。我在程序启动时调用它。
commands.put("test", new TestCommand());
}
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
String prefix = Settings.readSetting("Prefix"); // 在这里加载前缀。
if(event.getMessage().getContentDisplay().startsWith(prefix)) {
try {
Command c = commands.get(event.getMessage().getContentDisplay().split(" ")[0].substring(prefix.length())); // 这里发生了错误。
if(c != null) {
c.execute(event);
} else {
event.getChannel().sendMessage("抱歉,该命令不存在").queue();
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
有人知道这个错误和/或如何修复吗?
谢谢。
英文:
I am trying to write a discord bot.
Now i have the following problem:
First i load the prefix with String prefix = Setttings.readSetting("Prefix");
Then i test if the message received from the discord starts with the prefix.
If this test passes, i crop the Message and extract the command itself and execute
the method in the class of the method. But here's my problem:
When my prefix is longer than 1 character i get a 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)
Here's the code of the class:
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();
}
}
}
}
Does anyone know the error and/or how to fix it?
Thank you.
答案1
得分: 0
关于特定的异常:https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/
通常情况下,如果以某种方式访问数组(或字符串),使参数索引超出数组的索引范围,就会引发“IndexOutOfBoundsException”异常。
在你的情况下,异常被抛出,可能是因为你执行的字符串分割操作可能没有返回数组中索引为0的值,其长度足够长以包含“prefix.length()”。或者换个方式说:如果getMessage
返回的消息小于你的前缀长度会发生什么情况?
实际示例:
// 假设这是输入:
String prefix = "Hello";
String messageContentDisplay = "Hello Jack";
// 你的代码执行:
String[] segments = messageContentDisplay.split(" ");
String prefixInMessage = segments[0];
String subMessage = prefixInMessage.substring(prefix.length()); // 这是没有意义的。
我相信你实际想要的是截取前缀,可以这样实现:
String displayContent = event.getMessage().getContentDisplay();
String[] segments = displayContent.split(" ");
if (segments.length > 1) {
Command c = commands.get(displayContent.substring(segments[0].length));
}
英文:
First, about the specific exception: https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/
An IndexOutOfBoundsException
is usually thrown, if an array (or String
) is accessed in such a way, that the argument index is outside the array's index range.
In your case, the exception is thrown, because the string split you perform probably does not return a value in the array at index 0 that is as long as prefix.length()
. Or to put it another way: What happens if the message returned by getMessage
is smaller than the length of your prefix?
Practical example:
// 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.
I believe what you actually want is to cut the prefix, which would work like this:
String displayContent = event.getMessage().getContentDisplay();
String[] segments = displayContent.split(" ");
if (segments.length > 1) {
Command c = commands.get(displayContent.substring(segments[0].length));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论