如何重构方法使其仅抛出一个受检异常(符合SonarQube规范)
如何重构KeyManagerFactory获取方法使其仅抛出一个受检异常
问题场景
需求为实现一个获取javax.net.ssl.KeyManagerFactory的方法,初始实现代码如下:
public final KeyManagerFactory getKeyManagerFactory() throws GeneralSecurityException, IOException { final var keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); try (InputStream file = new FileInputStream(keyStoreLocation)) { final var keyStore = KeyStore.getInstance(PKCS12); keyStore.load(file, keyStorePassword.toCharArray()); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); return keyManagerFactory; } }
经SonarQube扫描后收到告警提示:重构此方法使其最多抛出一个受检异常。当前方法已将UnrecoverableKeyException、KeyStoreException等具体异常简化为抛出GeneralSecurityException和IOException,但仍不满足要求;同时不能使用throws Exception(会触发另一SonarQube问题),需要找到合规的重构方案。
解决方案
1. 定义自定义受检异常
创建一个业务语义明确的自定义受检异常,用于统一包装所有初始化过程中可能出现的异常:
public class KeyManagerFactoryInitializationException extends Exception { public KeyManagerFactoryInitializationException(String message, Throwable cause) { super(message, cause); } }
2. 修改原方法逻辑
调整原方法,捕获所有可能的GeneralSecurityException和IOException,将它们包装为自定义异常抛出:
public final KeyManagerFactory getKeyManagerFactory() throws KeyManagerFactoryInitializationException { try { final var keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); try (InputStream file = new FileInputStream(keyStoreLocation)) { final var keyStore = KeyStore.getInstance(PKCS12); keyStore.load(file, keyStorePassword.toCharArray()); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); return keyManagerFactory; } } catch (GeneralSecurityException | IOException e) { throw new KeyManagerFactoryInitializationException("初始化KeyManagerFactory失败", e); } }
方案说明
- 自定义异常具备明确的业务含义,相比泛用的
Exception更利于代码维护和异常排查 - 通过多异常捕获语法一次性处理两类异常,统一包装后仅抛出一个受检异常,完全满足SonarQube的要求
- 构造自定义异常时传递了原异常的堆栈信息,保留了异常根源,不影响问题定位
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

