Java 业务参数校验/断言工具类

本文介绍了如何通过创建一个Assert工具类来简化和优化Java后端业务逻辑中的断言式校验代码,将原本分散的判断逻辑集中处理,提高代码的可读性和维护性。示例中展示了如何使用这个工具类进行对象判空、数值比较等常见校验,并提供了异常定制功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常,我们在写后端业务逻辑时,可能会存在多处,像如下断言式的校验代码,在不满足条件时,即时中断业务:

    public static void main(String[] args) {

        // 伪代码

        // 业务判空
        if (xxx == null) {
            throw new RuntimeException("xxx 不能为空");
        }
        ....
        
        // 模拟转账业务
        BigDecimal balance = new BigDecimal(100);// 查询数据库的转账人余额
        BigDecimal transfer = new BigDecimal(50);// 订单转出金额
        if (balance.compareTo(transfer) == -1) {
            throw new RuntimeException("钱不够!");
        }
        ....

        // 模拟限制次数业务
        Integer count = 3; // 查询到的当前操作次数
        Integer limit = 3; // 查询到的最大限制次数
        if (count >= limit) {
            throw new RuntimeException("已达次数上限");
        }
        ....
    }

少量写起来倒也无妨,但一旦校验的东西多了,这种校验代码就会变得又臭又长,阅读时,也需费时思考校验的逻辑。

于是,我们来定义一个Assert工具类来消除该重复,简化校验逻辑。

/**
 * 断言工具类
 *
 * @Author zaiLuShang
 *
 */
public class Assert {

    private Assert() {
    }

    /**
     * @param t          待校验参数
     * @param verifier   参数校验器
     * @param exSupplier 异常构造器
     * @param <T>        校验类型
     * @param <E>        异常类型
     *                   满足性校验:使用 verifier 传入待校验参数 t,要求参数必须满足校验条件
     *                   (必须返回 true,当返回 false 时则抛出 exSupplier 制造的异常)
     */
    public static <T, E extends RuntimeException> void isTrue(T t, Predicate<T> verifier, Supplier<E> exSupplier) {
        Objects.requireNonNull(verifier, "verifier is null");
        Objects.requireNonNull(exSupplier, "exSupplier is null");
        // 断言结果
        boolean asserted = verifier.test(t);
        // 要求断言必须通过
        ifNotThrow(asserted, exSupplier);
    }

    /**
     * @param t          待校验参数
     * @param verifier   参数校验器
     * @param exSupplier 异常构造器
     * @param <T>        校验类型
     * @param <E>        异常类型
     *                   不满足性校验:使用 verifier 传入待校验参数 t,要求参数必须不满足校验条件
     *                   (必须返回 false,当返回 true 时则抛出 exSupplier 制造的异常)
     */
    public static <T, E extends RuntimeException> void isFalse(T t, Predicate<T> verifier, Supplier<E> exSupplier) {
        Objects.requireNonNull(verifier, "verifier is null");
        Objects.requireNonNull(exSupplier, "exSupplier is null");
        // 断言结果
        boolean asserted = verifier.test(t);
        // 要求断言必须不通过
        ifThrow(asserted, exSupplier);
    }

    /**
     * @param left       待校验参数1
     * @param right      待校验参数2
     * @param verifier   参数校验器
     * @param exSupplier 异常构造器
     * @param <T>        校验参数类型1
     * @param <U>        校验参数类型2
     * @param <E>        异常类型
     *                   满足性校验:使用 verifier 传入待校验参数 left,right,要求参数必须满足校验条件
     *                   (必须返回 false,当返回 true 时则抛出 exSupplier 制造的异常)
     */
    public static <T, U, E extends RuntimeException> void isTrue(T left, U right, BiPredicate<T, U> verifier, Supplier<E> exSupplier) {
        Objects.requireNonNull(verifier, "verifier is null");
        Objects.requireNonNull(exSupplier, "exSupplier is null");
        // 断言结果
        boolean asserted = verifier.test(left, right);
        // 要求断言必须通过
        ifNotThrow(asserted, exSupplier);
    }

    /**
     * @param left       待校验参数1
     * @param right      待校验参数2
     * @param verifier   参数校验器
     * @param exSupplier 异常构造器
     * @param <T>        校验参数类型1
     * @param <U>        校验参数类型2
     * @param <E>        异常类型
     *                   不满足性校验:使用 verifier 传入待校验参数 left,right,要求参数必须满足校验条件
     *                   (必须返回 false,当返回 true 时则抛出 exSupplier 制造的异常)
     */
    public static <T, U, E extends RuntimeException> void isFalse(T left, U right, BiPredicate<T, U> verifier, Supplier<E> exSupplier) {
        Objects.requireNonNull(verifier, "verifier is null");
        Objects.requireNonNull(exSupplier, "exSupplier is null");
        // 断言结果
        boolean asserted = verifier.test(left, right);
        // 要求断言必须不通过
        ifThrow(asserted, exSupplier);
    }

    /********************************************** 快速抛出异常的方法 **********************************************/
    public static <E extends RuntimeException> void ifThrow(boolean asserted, Supplier<E> exSupplier) {
        if (asserted) throw exSupplier.get();
    }

    public static <E extends RuntimeException> void ifNotThrow(boolean asserted, Supplier<E> exSupplier) {
        ifThrow(!asserted, exSupplier);
    }

    /********************************************** 以下为断言时的常用方法,提供静态方法引用 **********************************************/
    // 对象为空
    public static <T> boolean isNull(T t) {
        return Objects.isNull(t);
    }

    // 对象非空
    public static <T> boolean isNotNull(T t) {
        return Objects.nonNull(t);
    }

    // str 非空
    public static boolean strNotBlank(String str) {
        return isNotNull(str) && !str.isBlank();
    }

    // 集合非空
    public static <T> boolean collectionNotEmpty(Collection<T> collection) {
        return isNotNull(collection) && !collection.isEmpty();
    }

    // 数组非空
    public static <T> boolean arrayNotEmpty(T[] array) {
        return isNotNull(array) && array.length > 0;
    }

    // str 正则匹配
    public static boolean strRgx(String str, String regex) {
        return isNotNull(str)
                && isNotNull(regex)
                && Pattern.matches(regex, str);
    }

    // 对象相等
    public static <T, U> boolean isEq(T left, U right) {
        return Objects.equals(left, right);
    }

    // 对象不相等
    public static <T, U> boolean isNotEq(T left, U right) {
        return !isEq(left, right);
    }

    // 比较后相等,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderEq(T caller, T reference) {
        return caller.compareTo(reference) == 0;
    }

    // 比较后不相等,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderNotEq(T caller, T reference) {
        return !isOrderEq(caller, reference);
    }

    // 比较后大于,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderGt(T caller, T reference) {
        return caller.compareTo(reference) > 0;
    }

    // 比较后大于等于,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderGe(T caller, T reference) {
        return caller.compareTo(reference) >= 0;
    }

    // 比较后小于,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderLt(T caller, T reference) {
        return caller.compareTo(reference) < 0;
    }

    // 比较后小于等于,不做判空校验,逻辑不允许
    public static <T extends Comparable<T>> boolean isOrderLe(T caller, T reference) {
        return caller.compareTo(reference) <= 0;
    }
}

使用时,只需如下:

    public static void main(String[] args) {
        // 异常抽取为供给型函数式接口,可以定制异常
        // 单个对象判空
        Assert.isTrue(null, Assert::isNotNull, () -> new RuntimeException("要求非空"));
        Assert.isTrue(1, 1, Assert::isOrderEq, () -> new MyRuntimeException("要求相等"));
        Assert.isTrue(1f, 2f, Assert::isOrderGt, () -> new YourRuntimeException("要求大于"));
        Assert.isTrue(new Date(), new Date(), Assert::isOrderLt, () -> new HisRuntimeException("要求小于"));
        
        Assert.isTrue(1l, 2l, Assert::isOrderLe, () -> new HerRuntimeException("要求xxx"));
        Assert.isTrue(1d, 2d, Assert::isOrderLe, () -> new RuntimeException("要求xxx"));
        Assert.isTrue(new BigDecimal(1), new BigDecimal(2), Assert::isOrderLe, () -> new RuntimeException("要求xxx"));

        // 自定义
        Assert.isTrue(1, 1, (l, r) -> l > r, () -> new IllegalArgumentException("l 不大于 r"));
    }

代码变得干净又卫生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值