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

Java中Either类的使用与错误处理:结合自定义类的技术咨询

用Either类结合Human/Weapon/Magazine实现状态处理与错误处理

看起来你想通过Either类优雅处理Human实例的三种状态(无武器、无弹匣、装备齐全),同时规范错误处理逻辑。我来一步步帮你实现这个场景:

1. 先定义基础实体类

咱们先把Human、Weapon、Magazine的基础结构写好,确保它们能准确表达自身状态:

class Magazine {
    private final int capacity;

    public Magazine(int capacity) {
        if (capacity <= 0) {
            throw new IllegalArgumentException("弹匣容量必须大于0");
        }
        this.capacity = capacity;
    }

    public int getCapacity() {
        return capacity;
    }
}

class Weapon {
    private final Magazine magazine;

    public Weapon(Magazine magazine) {
        this.magazine = magazine;
    }

    public Magazine getMagazine() {
        return magazine;
    }

    // 判断武器是否有可用弹匣
    public boolean hasMagazine() {
        return magazine != null;
    }
}

class Human {
    private final Weapon weapon;

    public Human(Weapon weapon) {
        this.weapon = weapon;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    // 判断人类是否持有武器
    public boolean hasWeapon() {
        return weapon != null;
    }
}

2. 实现通用Either类

Either是典型的代数数据类型,用来表示「要么是错误信息,要么是有效对象」。咱们实现一个泛型版本,方便复用:

import java.util.function.Function;

// 抽象父类
abstract class Either<L, R> {
    // 禁止直接实例化
    private Either() {}

    // match方法:统一处理Left和Right两种情况
    public abstract <T> T match(Function<L, T> leftHandler, Function<R, T> rightHandler);

    // Left子类:存储错误信息
    public static class Left<L, R> extends Either<L, R> {
        private final L value;

        public Left(L value) {
            this.value = value;
        }

        @Override
        public <T> T match(Function<L, T> leftHandler, Function<R, T> rightHandler) {
            return leftHandler.apply(value);
        }
    }

    // Right子类:存储有效对象
    public static class Right<L, R> extends Either<L, R> {
        private final R value;

        public Right(R value) {
            this.value = value;
        }

        @Override
        public <T> T match(Function<L, T> leftHandler, Function<R, T> rightHandler) {
            return rightHandler.apply(value);
        }
    }

    // 静态工厂方法,简化对象创建
    public static <L, R> Either<L, R> left(L value) {
        return new Left<>(value);
    }

    public static <L, R> Either<L, R> right(R value) {
        return new Right<>(value);
    }
}

3. 结合Either创建并校验Human实例

接下来写一个工具方法,根据Human的状态返回对应的Either对象:状态不符合预期(无武器/无弹匣)返回Left(错误描述),状态正常返回Right(有效Human):

public class HumanEitherDemo {
    public static Either<String, Human> createValidHuman(Human human) {
        if (!human.hasWeapon()) {
            return Either.left("该人类没有武器");
        } else if (!human.getWeapon().hasMagazine()) {
            return Either.left("该人类的武器没有弹匣");
        } else {
            return Either.right(human);
        }
    }

    public static void main(String[] args) {
        // 三种测试实例
        Human noWeapon = new Human(null);
        Human noMag = new Human(new Weapon(null));
        Human hasAll = new Human(new Weapon(new Magazine(2)));

        // 处理无武器的情况
        Either<String, Human> eitherNoWeapon = createValidHuman(noWeapon);
        String result1 = eitherNoWeapon.match(
            error -> "错误:" + error,
            validHuman -> "人类装备齐全,武器弹匣容量:" + validHuman.getWeapon().getMagazine().getCapacity()
        );
        System.out.println(result1); // 输出:错误:该人类没有武器

        // 处理无弹匣的情况
        Either<String, Human> eitherNoMag = createValidHuman(noMag);
        String result2 = eitherNoMag.match(
            error -> "错误:" + error,
            validHuman -> "人类装备齐全,武器弹匣容量:" + validHuman.getWeapon().getMagazine().getCapacity()
        );
        System.out.println(result2); // 输出:错误:该人类的武器没有弹匣

        // 处理装备齐全的情况
        Either<String, Human> eitherHasAll = createValidHuman(hasAll);
        String result3 = eitherHasAll.match(
            error -> "错误:" + error,
            validHuman -> "人类装备齐全,武器弹匣容量:" + validHuman.getWeapon().getMagazine().getCapacity()
        );
        System.out.println(result3); // 输出:人类装备齐全,武器弹匣容量:2
    }
}

4. 错误处理的扩展思路

  • 如果需要更细粒度的错误区分,可以把Left的类型从String改成自定义枚举(比如ErrorType.NO_WEAPON、ErrorType.NO_MAGAZINE),后续处理错误时能精准分支。
  • 可以在Human/Weapon的构造方法里提前做参数校验(比如Weapon不允许传入null弹匣),但用Either的好处是可以把错误延迟到使用时统一处理,灵活性更高。
  • 可以扩展Either的方法,比如添加isLeft()/isRight()判断,或者getOrElse()方法提供默认值。

内容的提问来源于stack exchange,提问作者Cole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:35:21