● 安全防控
是的,没错,但在我 10 余年的编程生涯里,相信我 setDisable(false) 遇到过无数次;
// 堆代码 duidaima.com public static void main(String[] args) { convert("12.3456", 2, true); } /** * 将字符串转换成指定小数位数的值 * * @param value * @param scale * @param enableHalfUp 是否需要四舍五入 * @return */ public static String convertToValue(String value, int scale, boolean enableHalfUp) { if (enableHalfUp){ //将字符串"四舍五入"换成指定小数位数的值 }else{ //将字符串"截断"换到指定小数位数的值 } }当然,现在 IDE 都有比较好的提示,但从“可读性”角度,是不是只能进入到方法定义看注释去了解,甚至没有注释还得去翻代码去研究这个 boolean 到底是啥语义,参数再爆炸下,你能知道每个 boolean 类型参数代表什么吗?
convert("12.3456", 2, true,false,true,false,true);这里额外扩展一句,木宛哥搞过一段时间的 iOS 开发,如果是 Objective-C 语言,方法命名采用了较为直观的格式,可以包含多个参数名称“线性叙事”,以提高可读性。这种情况,boolean 变量前往往有“名词修饰”,会容易理解,如下所示:
public static void main(String[] args) { BigDecimal value = new BigDecimal("12.34567"); //四舍五入到两位小数 BigDecimal roundedValue = value.setScale(2, RoundingMode.HALF_UP); System.out.println(roundedValue); }看到了没,BigDecimal 的 setScale 方法,通过定义枚举:RoundingMode 代表转换规则,看到:RoundingMode.HALF_UP 一眼就知道要四舍五入,根本不需要看代码。这样增加了可读性的,同时定义了枚举也支持更多扩展,如下马上引入第二点好处:可扩展;
public void configureFeature(boolean enable) { if (enable) { // 开启功能 } else { // 关闭功能 } }使用枚举表达功能状态:
public enum FeatureMode { ENABLED, DISABLED, MAINTENANCE } public void configureFeature(FeatureMode mode) { switch (mode) { case ENABLED: // 开启功能 break; case DISABLED: // 关闭功能 break; case MAINTENANCE: // 维护状态 break; default: throw new IllegalArgumentException("Unknown mode: " + mode); } }类型安全
public static void main(String[] args) { if (checkIfMatched("Dummy")){ System.out.println("matched"); } } /** * 老旧系统里一个异常复杂的方法,有几千行 * @param str * @return */ public static Boolean checkIfMatched(String str) { Boolean matched; //假设此处存在:复杂处理逻辑,暂时用dummy代替 if ("Dummy".equals(str)) { matched = true; } else { matched = false; } return matched; }目前没问题,但当功能不断迭代后,复杂度也陡然上升,在某个特别的分支里,没有对 Boolean 赋值,至少在编译时是不会报错的:
public static void main(String[] args) { if (checkIfMatched("Dummy")) { System.out.println("matched"); } } /** * 老旧系统里一个异常复杂的方法,有几千行 * * @param str * @return */ public static Boolean checkIfMatched(String str) { Boolean matched = null; //假设此处存在:复杂处理逻辑,暂时用 dummy 代替 if ("Dummy".equals(str)) { //模拟:代码在演进的时候,有可能存在 matched 未赋值情况 if (false) { matched = true; } } else { matched = false; } return matched; }这个时候,危险悄然而至,还记得上面的问题吗:
if (checkIfMatched("Dummy")) { System.out.println("matched"); }首先这里不会编译错误,但此处 if 条件处会自动拆箱,对于 null 值会得到 NullPointerException 异常;