Java如何实现enum工厂 根据参数动态选择同结构枚举类
最优实现方案
核心思路是抽取公共接口统一不同State枚举的行为,保留枚举原生特性的同时实现动态匹配,不需要把枚举改为普通类,也几乎没有额外样板代码。
方案1:枚举内置关联(最简洁,推荐绝大多数场景使用)
步骤1:定义公共State接口
把所有State枚举共有的属性和方法抽象为接口,不同国家的State枚举都实现该接口:
public interface State { // 抽取所有State枚举共有的getter方法 String getCapital(); }
步骤2:不同国家的State枚举实现接口
public enum StateUS implements State { CALIFORNIA("Sacramento"), TEXAS("Austin"); private final String capital; StateUS(String capital) { this.capital = capital; } @Override public String getCapital() { return capital; } } public enum StateIN implements State { KARNATAKA("Bangalore"), MAHARASHTRA("Mumbai"); private final String capital; StateIN(String capital) { this.capital = capital; } @Override public String getCapital() { return capital; } }
步骤3:Countries枚举内置State关联逻辑
不需要额外写工厂类,直接把对应State枚举的关联逻辑放到Countries枚举里:
public enum Countries { US(StateUS.class), IN(StateIN.class); private final Class<? extends Enum<? extends State>> stateEnumClass; Countries(Class<? extends Enum<? extends State>> stateEnumClass) { this.stateEnumClass = stateEnumClass; } // 直接获取对应国家的所有State枚举实例 public State[] getStates() { return stateEnumClass.getEnumConstants().clone(); } // 如需使用枚举原生能力(比如valueOf匹配名称)可以获取枚举类 public Class<? extends Enum<? extends State>> getStateEnumClass() { return stateEnumClass; } }
最终使用
public State[] getStates(Countries country){ return country.getStates(); }
方案2:独立工厂类(适合匹配逻辑复杂的场景)
如果不想把关联逻辑耦合在Countries枚举中,可以单独实现工厂类做匹配:
public class StateEnumFactory { private static final Map<Countries, Class<? extends Enum<? extends State>>> STATE_ENUM_MAPPING = Map.of( Countries.US, StateUS.class, Countries.IN, StateIN.class ); public static State[] getStates(Countries country) { Class<? extends Enum<? extends State>> enumClazz = STATE_ENUM_MAPPING.get(country); if (enumClazz == null) { throw new IllegalArgumentException("不支持的国家类型:" + country); } return enumClazz.getEnumConstants(); } public static Class<? extends Enum<? extends State>> getStateEnumClass(Countries country) { Class<? extends Enum<? extends State>> enumClazz = STATE_ENUM_MAPPING.get(country); if (enumClazz == null) { throw new IllegalArgumentException("不支持的国家类型:" + country); } return enumClazz; } }
方案优势
- 完全保留枚举原生特性:
==比较、valueOf、values、ordinal等能力不需要手动实现 - 无冗余样板代码:仅需多定义一个公共接口,不需要把枚举改为普通类
- 扩展成本低:后续新增国家只需要新增对应State枚举,再加一行关联配置即可
常见业务场景示例
比如根据国家和州名称校验合法性,直接复用枚举原生的valueOf能力:
public boolean isValidState(Countries country, String stateName) { Class<? extends Enum> stateEnum = (Class<? extends Enum>) StateEnumFactory.getStateEnumClass(country); try { Enum.valueOf(stateEnum, stateName.trim().toUpperCase()); return true; } catch (IllegalArgumentException e) { return false; } }
内容的提问来源于stack exchange,提问作者Jnana
相关产品推荐
相关产品推荐

