java - Discord JDA Bot 在调用扩展类时抛出 NullPointerException
问题描述
我目前正在尝试在 JDA 中编写一个非常基本的 Discord 机器人,并且在尝试将我的代码巧妙地分成 Main Class、a MessageHandler
、aCommandHandler
和VoiceHandler
class 时遇到了一个问题。
如果收到事件,主类将添加一个 EventListener 来调用 MessageHandler,如果在命令之前看到机器人前缀,则分支到 CommandHandler。
问题是当它尝试调用 CommandHandler 时会抛出 NullPointerException new CommandHandler.handleCmd
。错误消息说"ERROR JDA - One of the EventListeners had an uncaught exception"
但是如果我没记错的话,它应该只是分支到 CommandHandler 类的 handleCmd 函数。所以我不明白为什么它会产生错误。
任何帮助将不胜感激!
这是我的主要课程
import net.dv8tion.jda.api.AccountType;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import javax.security.auth.login.LoginException;
public class Main extends ListenerAdapter {
public static void main(String[] args) throws LoginException {
JDABuilder builder = new JDABuilder(AccountType.BOT);
String token = "somethingsomething";
builder.setToken(token);
builder.addEventListeners(new MessageHandler()); //Puts Eventlistener to trigger MessageHandler
builder.build();
}
}
哪个应该触发我的 MessageHandler
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class MessageHandler extends ListenerAdapter {
protected String userName;
protected String userMessage;
protected MessageReceivedEvent event;
public void onMessageReceived(MessageReceivedEvent event) {
userName = event.getAuthor().getName();
userMessage = event.getMessage().getContentRaw();
this.event = event;
if (event.getAuthor().isBot()) {
return;
} else if (userMessage.startsWith(">")) {
new CommandHandler().handleCmd(); //Should trigger CommandHandler (this is the problem)
}
}
}
然后分支到 CommandHandler
public class CommandHandler extends MessageHandler {
private String command = userMessage.substring(1);
public void handleCmd() {
switch (command) {
case "join":
new VoiceHandler().join();
break;
case ... :
...
break;
case ... :
...
break;
}
}
}
VoiceHandler.join() 方法只是让机器人连接到我的语音通道,但现在应该无关紧要
如果有帮助,这里还有完整的错误消息
[JDA MainWS-ReadThread] ERROR JDA - One of the EventListeners had an uncaught exception
java.lang.NullPointerException
at CommandHandler.<init>(CommandHandler.java:2)
at MessageHandler.onMessageReceived(MessageHandler.java:17)
at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:376)
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:151)
at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:122)
at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:36)
at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:853)
at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:741)
at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:720)
at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:891)
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)
解决方案
堆栈跟踪告诉您异常发生在哪一行(第 2 行CommandHandler
)。
您的字段userMessage
是null
并且您正在对其执行方法调用。如果userMessage
尚未在您的 CommandHandler 中设置 ,则会发生这种情况。
以下代码
userMessage = event.getMessage().getContentRaw();
仅在当前 MessageHandler 对象中设置 userMessage。这些值不与新创建的 CommandHandler 对象共享。您需要使用构造函数或使用方法参数显式设置它们。您还可以将这些字段更改为静态字段。
使用构造函数的外观:
public class CommandHandler extends MessageHandler {
private String command;
/**
* You can add more parameters to this constructor or also a MessageHandler object.
**/
public CommandHandler(String userMessage){
if(userMessage != null){
this.comand = userMessage.substring(1);
}
}
public void handleCmd() {
switch (command) {
case "join":
new VoiceHandler().join();
break;
case ... :
...
break;
case ... :
...
break;
}
}
}
对象创建如下所示:
if (event.getAuthor().isBot()) {
return;
} else if (userMessage.startsWith(">")) {
new CommandHandler(userMessage).handleCmd();
}
问题是为什么需要扩展MessageHandler?您像使用实用程序类一样使用它,因此我建议将其更改为实用程序类:
public final class CommandHandler {
public static void handleCmd(String userMessage) {
if(userMessage == null){
return;
}
String command = userMessage.substring(1);
switch (command) {
case "join":
new VoiceHandler().join();
break;
case ... :
...
break;
case ... :
...
break;
}
}
}
以及该方法的调用:
CommandHandler.handleCmd(userMessage);
推荐阅读
- php - 函数 ReflectionParameter::export() 已弃用 7.4,替代方案?
- sql - 查询 SQL Server 的列顺序错误 - 没有人能回答这个问题
- dll - HotPlug.dll,Windows 7 中的 dll 调用
- python - 如何从给定的模块名称列表中导入函数?
- python - 在 read_sql_query 中使用 chunksize 后获取“ValueError:只能比较标记相同的 DataFrame 对象”
- python - ASGI“寿命”协议似乎不受支持
- python - 如何将名称列添加到现有的 numpy 数组?
- python - 输入密集与层无效形状不兼容
- json - 我将 javascript axios 生成的 json 格式消息发送到 GCP 上的 python 烧瓶服务器。但被拒绝
- java - 为什么合并的通量不会同时交错?