Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.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_Performance_Optimization_Reflection - Fatal编程技术网

Java 如何简化大型开关盒表达式?

Java 如何简化大型开关盒表达式?,java,performance,optimization,reflection,Java,Performance,Optimization,Reflection,我在下一个代码中遇到了一些问题。 我有简单的界面,如: public interface Game { int start(); } public class FirstGame implements Game { public static final int ID = 1; @Override int start() { // Do something and return result } } 许多实现此接口的类如下:

我在下一个代码中遇到了一些问题。 我有简单的界面,如:

public interface Game {
    int start();
}
public class FirstGame implements Game {
    public static final int ID = 1;
    
    @Override
    int start() {
        // Do something and return result
    }
}
许多实现此接口的类如下:

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;
}
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;
}
我试图使用如下反射来简化开关盒构造: 注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface GameId {

long value() default 0;
}
第一类游戏:

@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) {
    switch(id) {
        case FirstGame.ID:
            return new FirstGame();
        case SecondGame.ID:
            return new SecondGame();
        // ..... and many other cases....
    }
    return null;
}
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;
}
公共游戏getGameById(int-id){
Game=null;
试一试{
反射=新反射();
for(类clazz:reflections.getTypesAnnotatedWith(GameId.Class)){
if(clazz.getAnnotation(GameId.class).value()==id){
Constructor=clazz.getConstructor();
game=(game)构造函数.newInstance();
打破
}
}
}catch(异常ex){ex.printStackTrace();}
回归游戏;
}
但是它工作得太慢了。 那么,如何以其他方式简化开关大小写表达式呢? 谢谢,很抱歉英语不好。

这个怎么样

static final List<Supplier<Game>> GAMES = List.of(
    FirstGame::new,
    SecondGame::new
    // ...
);

public Game getGameById(int id) {
    return GAMES.get(id).get();
}
static final List GAMES=List.of(
FirstGame::新,
新游戏
// ...
);
公共游戏getGameById(int id){
return GAMES.get(id.get();
}

static final Map GAMES=Map.of(
1,FirstGame::新,
2,第二个游戏::新
);
公共游戏getGameById(int id){
return GAMES.get(id.get();
}
这个怎么样

static final List<Supplier<Game>> GAMES = List.of(
    FirstGame::new,
    SecondGame::new
    // ...
);

public Game getGameById(int id) {
    return GAMES.get(id).get();
}
static final List GAMES=List.of(
FirstGame::新,
新游戏
// ...
);
公共游戏getGameById(int id){
return GAMES.get(id.get();
}

static final Map GAMES=Map.of(
1,FirstGame::新,
2,第二个游戏::新
);
公共游戏getGameById(int id){
return GAMES.get(id.get();
}

感谢霍尔格的回答。
我反省的方法几乎成功了。它只需要将所有构造函数添加到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;
}
Map constructorMap=newhashmap();
私有void fillConstructorMap(){
试一试{
ConfigurationBuilder ConfigurationBuilder=新的ConfigurationBuilder();
configurationBuilder.addURL(ClasspathHelper.forPackage(“com.my.package.name”);
反射=新反射(configurationBuilder);
for(类clazz:reflections.getTypesAnnotatedWith(GameId.Class)){
整数id=clazz.getAnnotation(GameId.class).value();
Constructor=clazz.getConstructor();
constructorMap.put(id,constructor);
}
}catch(NoSuchMethodException-ex){
例如printStackTrace();
}
}
公共游戏getGameById(int id){
Game=null;
试一试{
game=(game)constructorMap.get(id).newInstance();
}catch(异常ex){ex.printStackTrace();}
回归游戏;
}

该方法的工作速度与使用开关盒表达式的方法一样快。

多亏了霍尔格的回答。 我反省的方法几乎成功了。它只需要将所有构造函数添加到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;
}
Map constructorMap=newhashmap();
私有void fillConstructorMap(){
试一试{
ConfigurationBuilder ConfigurationBuilder=新的ConfigurationBuilder();
configurationBuilder.addURL(ClasspathHelper.forPackage(“com.my.package.name”);
反射=新反射(configurationBuilder);
for(类clazz:reflections.getTypesAnnotatedWith(GameId.Class)){
整数id=clazz.getAnnotation(GameId.class).value();
Constructor=clazz.getConstructor();
constructorMap.put(id,constructor);
}
}catch(NoSuchMethodException-ex){
例如printStackTrace();
}
}
公共游戏getGameById(int id){
Game=null;
试一试{
game=(game)constructorMap.get(id).newInstance();
}catch(异常ex){ex.printStackTrace();}
回归游戏;
}

此方法的工作速度与使用开关大小写表达式的方法一样快。

只需执行一次,然后填充一个映射。如果要在case标签中描述字段<代码> ID <代码>的机制,它必须是代码>最终< /代码>。SAKA1029,您的权利。它出现在实际代码中,但在问题示例中没有。仅修复一次并填充地图。如果要在case标签中描述字段<代码> ID <代码>的机制,它必须是代码>最终< /代码>。SAKA1029,您的权利。它出现在实际代码中,但在问题示例中没有。修正谢谢你的回答,但我想阻止在创建新游戏类后将新游戏类名称添加到列表中。长列表看起来并不像它可以的那个样好。谢谢你们的回答,但我想防止在创建新游戏类后将新游戏类名称添加到列表中。长长的清单看起来并没有它能做到的那么好。