java - 避免 catch 子句中实际/逻辑上无法访问的代码

标签 java exception try-catch unreachable-code

我有一个界面:

public interface FileRepository {
    String insert(File file) throws IOException;
    // other methods ...
}

我的insert(File file)实现使用local(以避免并发问题)java.security.MessageDigester,它会抛出检查异常java.security.NoSuchAlgorithmException 来自其工厂方法。

public FileRepositoryImpl(String digestAlgo) throws NoSuchAlgorithmException {
    this.digestAlgo = digestAlgo;
    MessageDigest.getInstance(digestAlgo);
    }
@Override
public String insert(File file) throws IOException {
// initialize message digest
    MessageDigest messageDigest = null;
    try {
        messageDigest = MessageDigest.getInstance(digestAlgo);
    } catch (NoSuchAlgorithmException e) {
        LOGGER.fatal(MD_INIT_ERROR, e);
        return null;
}
    // other code ....
}
// other methods (may contain local MessageDigest)

我的做法:由于 NoSuchAlgorithmException 始终是 fatal error (这使得模块完全不可用),我尝试在构造函数中初始化 MessageDigest 来测试参数 digestAlgo,因此构造函数可以抛出异常,而不是从 insert(File) 抛出异常。另一个原因是接口(interface)不允许根据定义抛出 NoSuchAlgorithmException

我的问题:在我的实现中,代码

   } catch (NoSuchAlgorithmException e) {
        LOGGER.fatal(MD_INIT_ERROR, e);
        return null;
   }

永远不会到达,所以我认为应该有更好的解决方案,它可以避免(逻辑上和实际上)无法到达的代码。

欢迎任何解决方案/建议,谢谢。

编辑:

运行代码时这并不是真正的问题。但在测试中,由于代码不可达,加上一些“try-catch with resources”,质量分析工具(sonar、pmd)会认为代码“Insufficient Branch Coverage by Unit Tests”,这是测试中的一个主要问题。分析报告,这就是为什么我想避免这段代码。

另一个问题,在我的构造函数中测试 MessageDigest.getInstance(digestAlgo); 是一个好习惯吗?或者最好让 insert(File) 承担 NoSuchAlgorithmException 的全部责任?

最佳答案

这门课发生了太多事情。如果它是一个文件存储库,顾名思义,它的重点应该是存储文件,但是显然有很多与获取 MessageDigest 实例相关的不相关 Activity ——创建一种隧道(通过静态方法)对 MessageDigest 的依赖?依赖注入(inject)有许多选项,所有这些选项都使您能够将配置对象的责任转移到专用于该目的的框架(Spring、Guice、PicoContainer 等)。

我认为您已经意识到这里的问题,所以这是一个很好的开始。通常,您应该努力不抛出异常,并且通常对象构造函数是我最不喜欢这样做的地方之一。如果您使用框架来帮助您配置对象,那么您在这里面临的尴尬就可以完全消失。另外,您返回 null 的不是一次而是两次——它会让您在方法调用的另一端检查 null,您真的想这样做吗?如果您仔细考虑一下,我敢打赌您会想找到另一种方法(并且您确实有其他选择)。

此外,您会发现使用专门的对象创建工厂(这就是那些依赖注入(inject)框架)配置对象将帮助您更松散地将组件耦合在一起,这将提高在以下环境中测试组件的可能性与其真正的依赖关系隔离——使用模拟进行测试。如果您可以在做其他事情之前改变思维方式,在哪里为您希望拥有的代码编写单元测试,那么您应该会看到更好的设计几乎在不知不觉中开始发生。 GOOS本书是一个很好的入门资源。最美好的祝愿!

编辑:我读错了——看起来你只返回了一次 null,但这仍然是太多次了。 :-/

关于java - 避免 catch 子句中实际/逻辑上无法访问的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21472063/

相关文章:

java - 如何在 Java 中将包含字符串列表的 JsonNode 转换为逗号分隔的字符串

java - 通过 QuickFixJ 实现 FIX 客户端抛出 NoSuchMethodError

java - 客户端通过服务器与特定客户端通信

Javascript 多个 "try"s

c++ - 究竟什么时候捕获到异常?

java - 使用 JSON 反序列化为 Java 对象?

c++ - std::throw_with_nested() 在内存不足的情况下调用 std::terminate()

c# - 在 C# 中使用字典时出错

java - 在 spring mvc 中处理包装的异常

java - 即使从不抛出异常,使用 try-catch block 是否也很昂贵?