如何在枚举的异常信息中输出指定水果的对应类别值?
解决Fruit枚举中orElseThrow无法访问item的问题
问题分析
原代码的forValue方法存在两个问题:
- 当第二个
filter(校验category是否在允许列表)不匹配时,orElseThrow的lambda表达式无法访问前面的item变量——因为item的作用域仅局限于filter的lambda内部,流终止后该变量不再可用。 - 如果传入的
fruit名称不存在对应枚举实例,原代码的异常信息会因item未初始化而报错。
解决方案
将逻辑拆分为两步,确保能获取到目标枚举实例的category信息用于异常输出:
- 先找到与输入
fruit名称匹配的枚举实例,若不存在则抛出明确的异常。 - 单独校验该实例的category是否在允许列表中,若不匹配则使用该实例的category抛出目标异常。
修改后的完整代码如下:
public enum Fruit { MANGO("mango", "A"), APPLE("apple", "A"), CHERRY("cherry", "B"), BERRY("berry", "B"); private String fruit; private String category; private Fruit(String fruit, String category) { this.fruit = fruit; this.category = category; } public String getFruit() { return fruit; } public String getCategory() { return category; } public static Fruit forValue(final String fruit, final List<String> categories){ // 第一步:定位匹配fruit名称的枚举实例 Fruit targetFruit = Arrays.stream(Fruit.values()) .filter(item -> item.getFruit().equals(fruit)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No such fruit: " + fruit)); // 第二步:校验category是否合法 if (!categories.contains(targetFruit.getCategory())) { throw new IllegalArgumentException("Fruit only allowed with category " + targetFruit.getCategory()); } return targetFruit; } }
验证效果
执行你提供的测试代码:
List<String> categories = new ArrayList<>(); categories.add("A"); categories.add("Z"); Fruit.forValue("berry", categories);
会抛出符合预期的异常:IllegalArgumentException: Fruit only allowed with category B。
额外优化说明
- 拆分逻辑后代码可读性更强,每一步职责清晰。
- 针对“找不到对应fruit”的场景补充了准确的异常信息,避免了原代码潜在的无效变量访问问题。
内容的提问来源于stack exchange,提问作者user21061328
相关产品推荐
相关产品推荐

