You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在枚举的异常信息中输出指定水果的对应类别值?

解决Fruit枚举中orElseThrow无法访问item的问题

问题分析

原代码的forValue方法存在两个问题:

  • 当第二个filter(校验category是否在允许列表)不匹配时,orElseThrow的lambda表达式无法访问前面的item变量——因为item的作用域仅局限于filter的lambda内部,流终止后该变量不再可用。
  • 如果传入的fruit名称不存在对应枚举实例,原代码的异常信息会因item未初始化而报错。

解决方案

将逻辑拆分为两步,确保能获取到目标枚举实例的category信息用于异常输出:

  1. 先找到与输入fruit名称匹配的枚举实例,若不存在则抛出明确的异常。
  2. 单独校验该实例的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:23:11