应主动抛出 featuredisabledexception,而非静默跳过或用泛型异常;需封装检查逻辑、统一抛出,并在 web 层捕获返回 403/404,rpc 调用方降级处理,禁止用 illegalargumentexception 等替代或仅打日志。

在 Java 中使用特性开关(Feature Flag)时,若开关关闭而业务逻辑仍尝试执行对应功能,应主动抛出 FeatureDisabledException 来明确失败原因,而不是静默跳过或抛出泛型异常。关键在于:**检查开关状态 → 明确抛出自定义异常 → 确保调用方能感知并合理处理**。
定义 FeatureDisabledException
建议继承 RuntimeException(非检查异常),避免强制上层到处写 try-catch,同时保留语义清晰性:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
public class FeatureDisabledException extends RuntimeException {
private final String featureName;
public FeatureDisabledException(String featureName) {
super("Feature '" + featureName + "' is disabled");
this.featureName = featureName;
}
public FeatureDisabledException(String featureName, String message) {
super("Feature '" + featureName + "' is disabled: " + message);
this.featureName = featureName;
}
public String getFeatureName() {
return featureName;
}
}
在开关检查处统一抛出
不要在每个业务方法里重复判断 + throw,而是封装成工具方法或拦截逻辑:
- 使用工具类:
FeatureFlags.requireEnabled("payment_v2")内部调用开关服务,关闭则直接 throwFeatureDisabledException - 配合注解 + AOP(如 Spring @Aspect):对标注
@RequireFeature("search_suggestions")的方法,切面自动校验,不通过即抛异常 - 在门面服务或领域入口处检查,例如:
if (!featureToggleService.isEnabled("new_checkout_flow")) {<br> throw new FeatureDisabledException("new_checkout_flow");<br>}
确保异常被正确捕获和响应
抛出只是第一步,下游需有对应处理策略:
- Web 层(如 Spring MVC)可配
@ControllerAdvice统一捕获FeatureDisabledException,返回 403 或 404,附带提示信息(如{"error": "feature_not_available", "feature": "ai_summarize"}) - 内部 RPC 调用方应识别该异常,降级到旧逻辑或返回兜底数据
- 日志中记录异常时带上 featureName 和请求上下文(traceId、用户ID),便于排查“谁在调用已下线功能”
避免常见错误
- 不要用
IllegalArgumentException或UnsupportedOperationException替代 —— 语义不匹配,不利于监控和归因 - 不要只打印 warn 日志就继续执行 —— 这会让问题隐藏,下游误以为功能成功
- 不要在异步线程或定时任务中忽略该异常 —— 可能导致后台任务静默失败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










