我遇到了一些关于next代码的问题。我有一个简单的界面,比如:
public interface Game {
int start();
}许多实现此接口的类如下所示:
public class FirstGame implements Game {
public static final int ID = 1;
@Override
int start() {
// Do something and return result
}
}以及具有如下方法的GameManager类:
public Game getGameById(int id) {
switch(id) {
case FirstGame.ID:
return new FirstGame();
case SecondGame.ID:
return new SecondGame();
// ..... and many other cases....
}
return null;
}我试图使用如下的反射来简化这个switch-case结构:注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface GameId {
long value() default 0;
}FirstGame类:
@GameId(value = 1)
public class FirstGame implements Game {
public static final int ID = 1;
@Override
int start() {
// Do something and return result
}
}和如下的GameManager方法:
public Game getGameById(int id) {
Game game = null;
try {
Reflections reflections = new Reflections();
for (Class<?> clazz : reflections.getTypesAnnotatedWith(GameId.class)) {
if (clazz.getAnnotation(GameId.class).value() == id) {
Constructor constructor = clazz.getConstructor();
game = (Game) constructor.newInstance();
break;
}
}
} catch (Exception ex) { ex.printStackTrace();}
return game;
}但它的效果太慢了。那么,如何以其他方式简化switch-case表达式呢?感谢并为我糟糕的英语表达歉意。
发布于 2020-08-27 20:49:29
这个怎么样?
static final List<Supplier<Game>> GAMES = List.of(
FirstGame::new,
SecondGame::new
// ...
);
public Game getGameById(int id) {
return GAMES.get(id).get();
}或
static final Map<Integer, Supplier<Game>> GAMES = Map.of(
1, FirstGame::new,
2, SecondGame::new
);
public Game getGameById(int id) {
return GAMES.get(id).get();
}发布于 2020-08-27 21:52:11
感谢Holger的回答。我的反射方法非常接近成功。它只需要将所有构造函数添加到HashMap中一次,其中ID用作键。所以现在我的GameManager代码看起来像这样:
Map<Integer, Constructor> constructorMap = new HashMap<>();
private void fillConstructorMap() {
try {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.addUrls(ClasspathHelper.forPackage("com.my.package.name"));
Reflections reflections = new Reflections(configurationBuilder);
for (Class<?> clazz : reflections.getTypesAnnotatedWith(GameId.class)) {
Integer id = clazz.getAnnotation(GameId.class).value();
Constructor constructor = clazz.getConstructor();
constructorMap.put(id, constructor);
}
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
}
}
public Game getGameById(int id) {
Game game = null;
try {
game = (Game) constructorMap.get(id).newInstance();
} catch (Exception ex) {ex.printStackTrace();}
return game;
}此方法与使用switch-case表达式的方法一样快。
https://stackoverflow.com/questions/63615912
复制相似问题