当前位置: 首页 > 知识库问答 >
问题:

Discord JDA Bot在调用扩展类时引发NullPointerException

方嘉言
2023-03-14

我目前正在尝试用JDA编写一个非常基本的Discord bot,在试图将代码整齐地分为一个Main类、MessageHandlerCommandHandlerVoiceHandler类时,我遇到了一个问题。

如果接收到事件,主类将添加EventListener来调用MessageHandler,然后如果在命令之前看到bot前缀,则分支到CommandHandler。

问题是,当它试图用new CommandHandler.handlecmd调用CommandHandler时,会抛出一个NullPointerException。错误消息表示“Error JDA-EventListeners之一有一个未捕获的异常”,但是如果我没有错的话,它应该只会分支到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)
        }
    }
}
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;
        }
    }
}

如果有用的话,这里还有完整的错误信息

[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)

共有1个答案

刘博雅
2023-03-14

stacktrace告诉您异常发生在哪一行(CommandHandler的第2行)。

您的字段usermessagenull,并且您正在对其执行方法调用。如果CommandHandler中没有设置UserMessage就会发生这种情况。

下面的代码

userMessage = event.getMessage().getContentRaw(); 

如何使用构造函数:

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);
 类似资料:
  • 我正在做一个项目,该项目将有许多JavaFX应用程序,这些应用程序具有相似但又足够不同的功能,因此我创建了一个抽象基类来扩展Application以处理常见的功能并指示它们需要做什么,还创建了一系列具体的类来扩展这些功能。然而,当我试图跑的时候,我得到 应用程序构造函数java.lang.Reflect.InvocationTargetException位于java.base/jdk.intern

  • 我是构建web服务的新手,我开始使用spring boot构建web服务。我创建了以下controller类 尝试运行我的web服务会导致它抛出以下异常: 但是,如果我移除“ScheduledThreadPoolExecutor”和构造函数,它运行良好。谁能解释一下扩展课程有什么问题吗? 注: 1)扩展类是在下面提到的文章中建议的,作为我最初问题的解决方案。最初,我的runnable在没有任何类型

  • 问题内容: 所以对于这个项目,我试图在运行时扩展一个类。我想知道,这有可能吗?如果是这样,我该怎么办?是否有用于这些目的的库? 问题答案: CGLib是您要查找的库。它在扩展类或在运行时实现接口方面非常强大,因此许多流行的框架(如Spring或Hibernate)都使用它。 您可以使用以下代码创建类扩展 尽管您可能会使用具有所需逻辑的有用的方法拦截器替换回调。

  • 问题内容: 我有能力在编译时扩展一个类,但是我需要能够在运行时使用已实例化的超类的实例创建此子类的实例。 从理论上讲这应该是可能的,因为已经在子类构造函数之前调用了超类构造函数。 我没有足够的程序访问权限来更改实例化到我的子类或中断原始实例化。 用例:现有一个类X实例的数组。我的代码在之后加载。我需要使用已加载的子类Y扩展X来覆盖实例X之一的方法之一。父程序仅通过该数组访问对象,因此我想用Y实例替

  • 当我调用EmailSenderController上的addHtml()方法将html文件文本添加到html编辑器时,会引发错误。 类似的线程,但例外是我没有像他那样初始化@fxml inject控件:JavaFX FileChooser抛出错误(可能很容易修复,但仍然混乱) 主类

  • 问题内容: public class MyGeneric {} 据我所知,以上示例中的两个子类均有效。我想知道Java如何知道何时在实例化子类时定义超类中给定的类型,以及何时将它们定义为实际的类名(即,它如何知道T,E不是类名)? 旁注,是否允许(即使不常见)对通用类型使用多个字母?如果(由于某些严重的计划错误)类型与现有类冲突,该怎么办? 那会发生什么呢? 编辑:感谢您的及时答复。为了回答我的第