简体   繁体   English

如何将变量的参数化类型设置为变量所在的类类型?

[英]How do I set a parameterized type of a variable to the type of class the variable is in?

I am making a Discord bot with several 'command features'我正在制作一个具有多个“命令功能”的 Discord 机器人

public class MyBotCommandFeature extends MyBotFeature {
    @NotNull public final Set<MyBotCommand> commands;

    public MyBotCommandFeature(@NotNull MyBotCommand @NotNull ... commands) {
        if (commands.length == 0) {
            this.commands = new HashSet<>();
        } else {
            this.commands = stream(commands).collect(Collectors.toSet());
        }
    }

    @Nullable
    @CheckForNull
    @CheckReturnValue
    public Set<MyBotCommand> getExtraCommands(@NotNull Guild guild) {
        return null;
    }
}

Each feature has several commands (MyBotCommand).每个功能都有几个命令(MyBotCommand)。 MyBotCommand has two abstract methods for handling text commands (runTextCommand) and slash commands (runSlashCommand). MyBotCommand 有两种抽象方法用于处理文本命令 (runTextCommand) 和斜线命令 (runSlashCommand)。

Because some commands will want to refer to the MyBotFeature they're a part of, MyBotCommandFeature is currently one of the parameters of these abstract methods.因为某些命令会想要引用它们所属的MyBotFeatureMyBotCommandFeature当前是这些抽象方法的参数之一。 However, to use any feature-specific features, commands currently have to cast MyBotCommandFeature to, say, ExampleCommandFeature .但是,要使用任何特定于功能的功能,命令当前必须将MyBotCommandFeatureExampleCommandFeature

public abstract class MyBotCommand {
    public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull MyBotCommandFeature feature);
    public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull MyBotCommandFeature feature);
}
public final class ExampleFeature extends MyBotCommandFeature {
    public ExampleFeature() {
        super(new MyBotCommand() {
            @Override
            public void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull MyBotCommandFeature feature) {
                final ExampleFeature self = ((ExampleFeature) feature);
                // Use self to respond to the text command
            }

            @Override
            public void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull MyBotCommandFeature feature) {
                final ExampleFeature self = ((ExampleFeature) feature);
                // Use self to respond to the slash command
            }
        });
    }

I was hoping I'd be able to make MyBotCommand be parameterized with the generic type <F extends MyBotCommandFeature> .我希望我能够使用泛型类型<F extends MyBotCommandFeature>MyBotCommand进行参数化。 Then instead of the abstract functions taking MyBotCommandFeature as parameters, they'd take F .然后,它们不是将MyBotCommandFeature作为参数的抽象函数,而是采用F

public abstract class MyBotCommand<F extends MyBotCommandFeature> {
    public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull F feature);
    public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull F feature);
}

However, I'm not sure I would then declare the type of the set of commands (defined in MyBotCommandFeature , not individually in each feature) to say that the generic type F is the same as the class the set of commands is being stored in. I would want to be able to do something like this.但是,我不确定我是否会声明命令集的类型(在MyBotCommandFeature中定义,而不是在每个功能中单独定义)来说明通用类型 F 与存储命令集的类相同.我希望能够做这样的事情。

public class MyBotCommandFeature extends MyBotFeature {
    @NotNull public final Set<MyBotCommand<this>> commands;

    public MyBotCommandFeature(@NotNull MyBotCommand<this> @NotNull ... commands) {
        if (commands.length == 0) {
            this.commands = new HashSet<>();
        } else {
            this.commands = stream(commands).collect(Collectors.toSet());
        }
    }

    @Nullable
    @CheckForNull
    @CheckReturnValue
    public Set<MyBotCommand<this>> getExtraCommands(@NotNull Guild guild) {
        return null;
    }
}
public final class ExampleFeature extends MyBotCommandFeature {
    public ExampleFeature() {
        super(new MyBotCommand<ExampleFeature>() {
            @Override
            public void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull ExampleFeature feature) {
                // Use feature to respond to the text command
            }

            @Override
            public void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull ExampleFeature feature) {
                // Use feature to respond to the text command
            }
        });
    }

I have tried using a wildcard '?'我试过使用通配符'? instead of 'this' but then I'm stuck on what to pass to the abstract methods after matching a JDA event to a MyBotCommand.而不是“this”,但是在将 JDA 事件与 MyBotCommand 匹配后,我被困在传递给抽象方法的内容上。 For example, I have this for slash commands, but I am unable to pass MyBotCommandFeature to MyBotCommand::runSlashCommand even though the MyBotCommand instance is made in the MyBotCommandFeature I am passing.例如,我有这个用于斜杠命令,但我无法将 MyBotCommandFeature 传递给 MyBotCommand::runSlashCommand,即使 MyBotCommand 实例是在我传递的 MyBotCommandFeature 中创建的。

    @Override
    public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
        for (MyBotCommandFeature feature : features) {
            for (MyBotCommand<?> command : feature.commands) {
                if (command.name.equals(event.getName())) {
                    command.runSlashCommand(event,feature);
                    return;
                }
            }
        }
    }

Is there some way I can do something like this?有什么办法可以做这样的事情吗? If not, is there an alternative way to avoid having to cast MyBotCommandFeature to an individual feature in most of my MyBotCommand implementations?如果没有,是否有另一种方法可以避免在我的大多数MyBotCommand实现MyBotCommandFeature转换为单个功能?

How about something like this?这样的事情怎么样? There is a type variable on MyBotCommandFeature indicating the type argument of the MyBotCommand that its commands are. MyBotCommand MyBotCommandFeature类型参数。 Then the subclass ExampleFeature can extend MyBotCommandFeature with itself as the type argument.然后子类ExampleFeature可以扩展MyBotCommandFeature并将其自身作为类型参数。 Of course, someone could write a class FeatureA extends MyBotCommandFeature<FeatureB> , but everything is still type-safe and should compile without any warnings or casts, at least with what you've shown so far.当然,有人可以编写一个类FeatureA extends MyBotCommandFeature<FeatureB> ,但一切仍然是类型安全的,并且应该在没有任何警告或强制转换的情况下编译,至少与您目前所展示的一样。

public abstract class MyBotCommand<F> {
    public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull F feature);
    public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull F feature);
}

public class MyBotCommandFeature<F> extends MyBotFeature {
    @NotNull public final Set<MyBotCommand<F>> commands;

    public MyBotCommandFeature(@NotNull MyBotCommand<F> @NotNull ... commands) {
        if (commands.length == 0) {
            this.commands = new HashSet<>();
        } else {
            this.commands = stream(commands).collect(Collectors.toSet());
        }
    }

    @Nullable
    @CheckForNull
    @CheckReturnValue
    public Set<MyBotCommand<F>> getExtraCommands(@NotNull Guild guild) {
        return null;
    }
}

public final class ExampleFeature extends MyBotCommandFeature<ExampleFeature> {
    public ExampleFeature() {
        super(new MyBotCommand<ExampleFeature>() {
            // ...
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Class实例化参数化Type类 <?> 变量 - Instantiate Parameterized Type class with Class<?> variable 获取通用变量的参数化类型类 - Get parameterized type class of a generic variable 在Java中,如何在继承的类中覆盖变量的类类型? - In Java, how do I override the class type of a variable in an inherited class? 如何将默认值设置为注释变量作为注释变量的类类型? - How to set default value to annotation variable as the class type of the variable annotated? 为什么我不能将具有其他类型的实例分配给参数化变量? - Why can't I assign an instance with another type to a parameterized variable? 如何将类型作为变量传递? - How do I pass the type as a variable? C#中的参数化System.Type变量 - Parameterized System.Type Variable in C# 如何从另一个类中的public类型的参数化构造函数中调用默认类型的参数化构造函数? - How can I call parameterized constructor of default type from a parameterized constructor of type public which is in another class? 如何从参数化类型方法参数中获取参数化类型类? - How can I get the parameterized-type class from a parameterized-type method argument? 如何声明扩展参数化类型的类型变量? - How do I declare a type variable that extends a Parameterised type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM