Discord机器人脏话过滤器:跨类调用ArrayList输出为null问题
问题根源
你的代码里,脏话列表只有在ProfanityFile的main方法执行时才会从文件读取,但运行Discord机器人时,这个main方法根本不会被触发——机器人的入口是独立的启动类,因此ProfanityFile的静态list始终是空的,导致EventListener调用时拿不到有效数据。
修复方案
1. 重构ProfanityFile类
把文件读取逻辑从main方法移到静态初始化块,确保类加载时自动完成数据读取,同时简化获取列表的方法:
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Scanner; public class ProfanityFile { // 静态存储脏话列表 private static ArrayList<String> list = new ArrayList<>(); // 静态初始化块:类加载时自动执行文件读取 static { try (Scanner s = new Scanner(new File("profanityList.txt"))) { while (s.hasNext()) { list.add(s.next()); } } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("错误:脏话列表文件未找到!"); } } // 提供无参的列表获取方法 public static ArrayList<String> getList() { // 返回列表副本,避免外部代码修改原数据 return new ArrayList<>(list); } }
2. 修改EventListener类
只在类初始化时加载一次脏话列表,不需要每次收到消息都重复获取,同时跳过机器人自身的消息:
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import java.util.ArrayList; public class EventListener extends ListenerAdapter { // 类初始化时一次性加载脏话列表 private static final ArrayList<String> profanityList = ProfanityFile.getList(); @Override public void onMessageReceived(MessageReceivedEvent event) { // 跳过机器人发送的消息,避免循环触发 if (event.getAuthor().isBot()) return; String message = event.getMessage().getContentRaw(); // 用增强for循环遍历列表,代码更简洁 for (String profanity : profanityList) { if (message.contains(profanity)) { event.getMessage().delete().queue(); event.getChannel().sendMessage("Don't say that!").queue(); return; } } } }
额外优化说明
- 把
profanityList设为final,避免被意外修改 - 跳过机器人消息,防止机器人自身触发过滤逻辑
- 返回列表副本,避免外部代码篡改原脏话列表数据
内容的提问来源于stack exchange,提问作者derezzed
相关产品推荐
相关产品推荐

