当前位置: 首页 > 知识库问答 >
问题:

Java,可以将相同的异常处理逻辑合并到一个地方吗?

缑嘉玉
2023-03-14

我在清理一些Java代码。有许多静态工厂方法都执行相同的异常处理。例如,考虑< code>createA:

public static A createA() throws XXXX, YYYY {
    try {
        return somethingThatThrows();
    } catch (InterruptedException | ExecutionException e) {
        Throwable throwable = e.getCause();
        if (throwable instanceOf XXXX) {
            throw (XXXX) throwable;
        } else if (e instance of YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
    }
}         

有许多这样的创建方法(每个方法返回不同的类型)。对于这些方法中的每一个,都存在此异常处理的副本(即它是重复的)。我希望有一种方法可以避免所有这些相同的代码,并且只在一个地方有这个逻辑。

当然,在没有异常处理的情况下,您只需将逻辑提取到辅助函数并解决重复问题-这具有异常处理的事实使其与众不同。以下代码不构建:

public static void helper(final Exception e) {
    Throwable throwable = e.getCause();
        if (throwable instanceOf XXXX) {
            throw (XXXX) throwable;
        } else if (e instance of YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
}  

public static A createA() throws XXXX, YYYY {
    try {
        return somethingThatThrows();
    } catch (InterruptedException | ExecutionException e) {
        handle(e);
    }
}         

有人有什么建议吗?

共有2个答案

姜钊
2023-03-14

尝试将公共逻辑提取到私有方法中并调用它:

public static A createA() throws XXXX, YYYY {
    try {
        return somethingThatThrows();
    } catch (InterruptedException | ExecutionException e) {
       processInterruptedExcutionExceptions(e);
    }
    return null;
}

private static void processInterruptedExcutionExceptions(final Exception e) throws XXXX, YYYY {
        Throwable throwable = e.getCause();
        if (throwable instanceOf XXXX) {
            throw (XXXX) throwable;
        } else if (e instance of YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
}
长孙弘盛
2023-03-14

这可以按如下功能方式处理:

@FunctionalInterface
interface SomethingThatThrows<T> {
    T execute() throws XXXX, YYYY, InterruptedException,ExecutionException;
}

private static <T> T handledFuntion(SomethingThatThrows<T> function) throws XXXX, YYYY {
    try {
        return function.execute();
    } catch (InterruptedException | ExecutionException e) {
        Throwable throwable = e.getCause();
        if (throwable instanceof XXXX) {
            throw (XXXX) throwable;
        } else if (e instanceof YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
    }
}

// Use lambda literal - may be better when arguments are involved
public A createA(String arg1) throws XXXX, YYYY {
   return handledFuntion(() -> {
         // write code just like you'd write it in try{} body - 
         // all arguments to createA() are available
         return new A(arg1);
     });
}

// use a method handle, works best when there are no arguments
public B createB() throws XXXX, YYYY {
       return handledFuntion(this::somethingThatMakesB);
}


private B somethingOtherThatMakesB() throws XXXX, YYYY, InterruptedException,ExecutionException {
    // Some logic that creates and returns B
}

编辑:合并@Arkadiy的答案。

 类似资料:
  • 问题内容: 我认为人们普遍认为,作为Java(以及可能带有异常处理的任何语言)中的一条通用规则,应尽量避免使用异常处理来实际处理业务逻辑。通常,如果预期会发生某种情况,则应该检查并更直接地处理它,而不是依靠异常处理为您做检查。例如,以下情况不被认为是好的做法: 相反,延迟初始化应该更像这样完成: 当然,除了简单地处理延迟初始化之外,还可能存在更复杂的逻辑。因此,考虑到这种事情通常是令人生厌的……何

  • 问题内容: 我已经为,一旦文件被上传,然后我需要调用基于从解析器下拉列表中选择什么样的价值不同的解析器,然后解析器正在创建的对象,其中我打电话的那个特定的类方法,这里要注意的一点是,既不也不是在faces- config.xml中注册的,我的问题是 如果我想维护从一个班级到另一个班级的会话信息,那么我应该在其中定义它,但是应该如何定义和定义类,应该将它定义为其他名称还是其他名称? 这是代码: 在我

  • 问题内容: 不太熟悉JAVA或异常处理。寻找关于什么可以接受和什么被皱眉的建议。 该场景,我正在构建一个生活游戏程序,我设置了条件来检查一个单元格是否会超出范围,而不尝试访问该“单元格”。我的问题是,使用try catch块而不是8个条件语句是否可以接受,并且如果引发了arrayOutOfBounds异常,则什么也不做。即忽略细胞越界,或者这是不好的做法?例如… 在这种情况下,cellIsAliv

  • 问题内容: 我目前有大约10种测试,只要路径或墙壁上有一块,俄罗斯方块就不会向左移动。现在,我将必须测试正确动作的相同行为。 如果我只复制已经存在的10个用于左移动的测试,并仅进行所需的更改并对代码本身也做同样的操作,那是否太糟糕了?还是即使逻辑基本相同,我还是应该从头开始再次进行每个测试? 问题答案: 尝试采用您尚未提到的第三种方法,即重构代码,以便可以在所有10个测试之间共享该测试的一种实现。

  • 问题内容: Gradle可以将多个项目合并到一个jar中吗? 我知道您可以使用以下方法针对单个项目执行此操作: 但是一个人如何将多个子项目压缩到一个jar中呢? 我试过了,但不起作用: 问题答案: 这是我的解决方案,它稍微简单一些: 代码已在Gradle 1.12上进行了测试

  • 主要内容:异常简介,异常类型很多事件并非总是按照人们自己设计意愿顺利发展的,经常出现这样那样的异常情况。例如: 你计划周末郊游,计划从家里出发→到达目的→游泳→烧烤→回家。但天有不测风云,当你准备烧烤时候突然天降大雨,只能终止郊游提前回家。“天降大雨”是一种异常情况,你的计划应该考虑到这样的情况,并且应该有处理这种异常的预案。 计算机程序的编写也需要考虑处理这些异常情况。 异常(exception)是在运行程序时产生的一种异