[英]How do I resolve the unchecked cast problem IntelliJ is highlighting?
我正在為我的 CQRS 應用程序構建一個命令調度程序。
public interface Command {
}
public interface CommandExecutor<T extends Command> {
Mono<CommandResult> execute(T command);
}
public class CommandDispatcher {
private final Map<String, CommandExecutor<? extends Command>> executors = new HashMap<>();
// Example usage
public static void main(String[] args) {
CommandDispatcher dispatcher = new CommandDispatcher();
dispatcher.register(MakeRequestCommand.class.getName(), new MakeRequestCommandExecutor());
dispatcher
.dispatch(MakeRequestCommand.class.getSimpleName(), new MakeRequestCommand("Any iPhone"))
.subscribe(System.out::println);
}
public <T extends Command> void register(String commandAlias, CommandExecutor<T> executor) {
executors.put(commandAlias, executor);
}
public <T extends Command> Mono<CommandResult> dispatch(String commandAlias, T command) {
if (!executors.containsKey(commandAlias)) {
throw new RuntimeException("No executor registered for command %s".formatted(commandAlias));
}
CommandExecutor<T> executor = (CommandExecutor<T>) executors.get(commandAlias);
return executor.execute(command);
}
}
以下行在 IntelliJ 中產生警告。
CommandExecutor<T> executor = (CommandExecutor<T>) executors.get(commandAlias);
未經檢查的演員表:'io.freesale.application.command.CommandExecutor<capture<? 將 io.freesale.application.command.Command>>' 擴展到 'io.freesale.application.command.CommandExecutor'
這是我需要關心的事情嗎/有沒有辦法解決它(不抑制警告。)
我擔心它突出了我設計中的缺陷。
未經檢查的強制轉換字面意思是 - Java 無法檢查強制轉換是否有效(這是由於類型擦除),因此在強制轉換點不會有ClassCastException
,這通常會使它更難調試。
例如,如果您這樣做:
dispatcher.register(SomeTypeOfCommand.class.getName(), new SomeTypeOfCommandExecutor());
dispatcher
// we're getting the SomeTypeOfCommandExecutor, but giving it AnotherTypeOfCommand
.dispatch(SomeTypeOfCommand.class.getName(), new AnotherTypeOfCommand())
.subscribe(System.out::println);
SomeTypeOfCommandExecutor
是一個CommandExecutor<SomeTypeOfCommand>
。 如果檢查了轉換,Java 會發現將AnotherTypeOfCommand
為CommandExecutor<SomeTypeOfCommand>
是無效轉換,並在以下行拋出ClassCastException
:
CommandExecutor<T> executor = (CommandExecutor<T>) executors.get(commandAlias);
然而,轉換實際上是未經檢查的,所以ClassCastException
只會在稍后調用SomeTypeOfCommandExecutor.execute
時拋出。 此時, Java 可以看到傳入的參數不是SomeTypeOfCommand
。 這可能會導致混亂的堆棧跟蹤。
這就是警告警告您的內容。 IMO,這沒什么好擔心的,因為executor.execute(command);
在未經檢查的演員表之后不遠(緊接着),所以你基本上是在下一行立即“檢查”演員表。 如果您想更加清楚地知道您正在檢查演員表,您可以在CommandExecutor
中添加一個方法,如下所示:
boolean canExecute(Object command);
在實現中,您只需使用instanceof
來檢查command
。
旁注:如果每種類型的命令只能有一個命令執行程序,我建議您使用Class<?>
作為地圖的鍵類型。 這樣,在register
和dispatch
中,你可以要求 class 類型和命令的類型必須相同,這樣可以防止這樣的事情發生:
.dispatch(SomeTypeOfCommand.class, new AnotherTypeOfCommand())
你會這樣做:
private final Map<Class<? extends Command>, CommandExecutor<? extends Command>> executors = new HashMap<>();
public <T extends Command> void register(Class<T> commandAlias, CommandExecutor<T> executor) {
executors.put(commandAlias, executor);
}
public <T extends Command> Mono<CommandResult> dispatch(Class<T> commandAlias, T command) {
CommandExecutor<T> executor = (CommandExecutor<T>) executors.get(commandAlias);
if (executor == null) {
throw new RuntimeException("No executor registered for command %s".formatted(commandAlias));
}
return executor.execute(command);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.