sds*_*sds 2 java generics reflection
假设我有这个:
abstract class Command {
static void run (String[]argv) {}
}
class Slice extends Command {
static void run (String[]argv) {/* slicing code */}
}
class Dice extends Command {
static void run (String[]argv) {/* dicing code */}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够迭代命令,所以我写道:
Class<Command>[] commands = {Slice.class,Dice.class}; /* compile error */
for (Class<Command> c : commands) {
if (some_string.equals(c.getName()) {
c.getDeclaredMethod("run",String[].class).invoke(argv);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,它似乎Slice.class并且Dice.class不能放入同一个容器中Class<Command>.
如果我更换Class<Command>与Class无处不在,代码编译一个警告:
[unchecked] unchecked call to getDeclaredMethod(java.lang.String,java.lang.Class<?>...) as a member of the raw type java.lang.Class
c.getDeclaredMethod("run",String[].class).invoke(argv);
Run Code Online (Sandbox Code Playgroud)
当然,这可以被压制,但我想知道,有更优雅的解决方案吗?
(当然,在C中,这可以通过一个包含两个元素的结构数组来完成:一个字符串和一个指向函数的指针).
只有Command.class这种类型Class<Command>.它的所有子类型都属于这种类型Class<? extends Command>.如果将数组和迭代器类型更改为Class<? extends Command>,则其余代码应该有效.
Class<? extends Command>[] commands = {Slice.class,Dice.class};
for (Class<? extends Command> c : commands) {
if (some_string.equals(c.getName()) {
c.getDeclaredMethod("run",String[].class).invoke(argv);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
除非你需要反射,否则简单地拥有一个Command对象数组(这需要删除方法上的static关键字run)会更简单:
Command[] commands = {new Slice(), new Dice()};
for (Command cmd : commands) {
if (some_string.equals(cmd.getClass().getName())) {
cmd.run (argv);
return;
}
}
Run Code Online (Sandbox Code Playgroud)