Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 需要注释方法上的方法参数_Java - Fatal编程技术网

Java 需要注释方法上的方法参数

Java 需要注释方法上的方法参数,java,Java,我正在编写一个IRC机器人,它响应像这样的命令!时间,!说你好和类似的话。我遇到的一个挑战是,解析这些命令最终会得到一个很长的if/else包。为了避免if/else大崩溃的问题,我尝试使用注释向bot中添加额外的命令,这使代码看起来更干净,更易于维护和扩展 看起来是这样的, public class ExampleChatPlugin extends Plugin { @CommandMessage(command="!time") public void handleTime

我正在编写一个IRC机器人,它响应像
这样的命令!时间
!说你好
和类似的话。我遇到的一个挑战是,解析这些命令最终会得到一个很长的if/else包。为了避免if/else大崩溃的问题,我尝试使用注释向bot中添加额外的命令,这使代码看起来更干净,更易于维护和扩展

看起来是这样的,

public class ExampleChatPlugin extends Plugin {
    @CommandMessage(command="!time")
    public void handleTime(Bot bot, String channel, Command fullMessage) {
        bot.sendMessage(channel, "I don't know the time :(");
    }

    @CommandMessage(command="!sayHello")
    public void handleSayHello(Bot bot, String channel, Command fullMessage) {
        bot.sendMessage(channel, "Oh, hi there.");
    }

    // etc...
}
所以!我在超类
Plugin
中有一个消息处理方法,它确定在收到消息时调用哪个方法。这个方法在这里

public void callCommandMessages(String channel, String sender, String input) {
    Command command = new Command(input);

    for (Method m : this.getMethodsWithAnnotation()) {
        String keyword = m.getAnnotation(CommandMessage.class).keyword();

        if (keyword.isEmpty()) {
            keyword = m.getName();
        }

        if (command.supportsKeyword(keyword)) {
            if (m.getGenericParameterTypes().length < 4) {
                MessagePlugin.LOG.debug("InputSelector method found for " + input + ", but this method needs to 4 arguments");
            } else {
                try {
                    m.invoke(this, channel, sender, command);
                    return;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    System.out.println("Could not find: " + input);
}
public void callCommandMessages(字符串通道、字符串发送器、字符串输入){
命令=新命令(输入);
对于(方法m:this.getMethodsWithAnnotation()){
字符串关键字=m.getAnnotation(CommandMessage.class).keyword();
if(关键字.isEmpty()){
关键字=m.getName();
}
if(command.supportsKeyword(关键字)){
if(m.getGenericParameterTypes().length<4){
MessagePlugin.LOG.debug(“为“+input+”找到了InputSelector方法,但该方法需要4个参数”);
}否则{
试一试{
m、 调用(此、通道、发送方、命令);
返回;
}捕获(例外e){
e、 printStackTrace();
}
}
}
}
System.out.println(“找不到:“+输入”);
}
所以,我的问题是,这个方法检查
@CommandMessage
方法是否需要4个参数,但这不是很严格,最重要的是,它只在运行时检测到。糟透了

有没有一种方法可以让一个带注释的方法强制使用参数
Bot-Bot、字符串通道、字符串发送器、Command-Command

我知道最明显的方法是一个接口,因为这正是它们的设计目的,但这意味着为每个
@CommandMessage
都有一个类,这也太糟糕了

有没有办法让一个带注释的方法强制使用参数Bot Bot、String channel、String sender和Command

我不能马上想到用一种标准的方式来执行这个。然而,我已经通过编写单元测试来“解决”类似的问题,单元测试通过使用反射和包扫描来检查这类事情

  • 在预定义的java包中获取所有类
  • 迭代所有的方法
  • 如果存在
    @CommandMessage
    注释,请检查方法签名是否正确

但是,这取决于持续集成工作流,特别是只有当所有测试都成功运行时,代码的构建才会成功。

我建议这样的解决方案:

public interface PluginMethod {
    void execute(Bot bot, Channel channel, Sender sender, Command command);
    String getCommand();
}

public interface Plugin {
    List<PluginMethod> getPluginMethods();
}
公共接口插件方法{
无效执行(Bot-Bot、Channel-Channel、Sender-Sender、Command);
字符串getCommand();
}
公共接口插件{
列出getPluginMethods();
}

没有注释那么花哨,但您强制每个方法都使用4属性接口。

您能举一个您不喜欢看到的大型if/else包的例子吗?我原以为涉及注释的解决方案会过于成熟。这听起来像是注释处理器的工作(尽管它们编写起来相当复杂)。如果带注释的方法与参数列表不匹配,则启动时可能会失败。这还允许使用
映射在命令与其实现实例之间进行缓存。此外,您还可以使用
ServiceLoader
机制来发现自定义插件。是的,这将是解决问题的一种完全标准的方法,但我担心的是类的大量扩展——目前在100-120个命令的范围内。还有一些命令,如
!quidAdd
!quizStart
是直接相关的,最好将它们保持在同一个类中,以便它们可以共享功能。