在我关于JCG的第一篇文章中,我想向您展示如何利用Java语言的强大功能轻松地提高代码的可读性,即使是非常基本的事情。
让我们从一个具体的例子开始:
String color = "green";
...
if ( color!=null && color.equals("red") ) {System.out.println("Sorry, red is forbidden !");
}
您可能从Java(或面向对象编程)老师那里学到的第一课是在对象上调用方法之前测试对象的无效性的重要性。 空指针异常(NPE)确实是面向对象语言的代码中最常见(最令人讨厌)的错误。
在上面的示例中,可以安全地将'color'字符串对象与常量进行比较之前确保其不为null。 我个人一直认为这是程序员的不必要负担,尤其是对于Java等现代OO语言而言。 解决方法是,存在一个(确实很愚蠢的)技巧来重写条件而不必测试无效性。 请记住, equals()方法是对称的(如果a = b则b = a)。
if ( "red".equals(color) ) {System.out.println("Sorry, red is forbidden !");
}
乍一看,在阅读时可能会有些反常 ,但是消除污染代码当然也不是一文不值。
让我们继续我们的示例,并假设我们现在想将我们的颜色与多个值进行比较。 Java初学者通常会编写如下内容:
if ( "red".equals(color) ||"yellow".equals(color) ||"blue".equals(color) ) {System.out.println("This is a primary color");
}
我有时会遇到经验丰富的Java程序员,他们用以下代码缩短了很长的if语句:
if ( "red|yellow|blue".indexOf(color)>=0 ) {System.out.println("This is a primary color");
}
聪明吗? 实际上没有那么多。 与子字符串一起玩可能是一个危险的游戏。 例如,以下代码可能不会给出预期的结果,特别是如果您是男人:
String type = "man";
...
if ( "woman|child".indexOf(type)>=0 ) {System.out.println("Women and children first !");
}
如果您希望在美观和可读性之间找到良好的平衡,则最好选择以下替代方法之一。
import java.util.HashSet;
import java.util.Set;public static final Set<string> PRIMARY_COLORS;
static {PRIMARY_COLORS = new HashSet<string>();PRIMARY_COLORS.add("red");PRIMARY_COLORS.add("yellow");PRIMARY_COLORS.add("blue");
}
...
if ( PRIMARY_COLORS.contains(color) ) {System.out.println("This is a primary color");
}
很少有人知道这一点(我承认语法有点奇怪),但是在初始化“原色集 ”时仍然有一种减少代码冗长的方法:
public static final Set<string> PRIMARY_COLORS = new HashSet<string>() {{ add("red"); add("yellow"); add("blue");
}};
如果对代码的简洁性变得痴迷,那么Java Collections Framework也可以解决:
import java.util.Arrays;
import java.util.Collection;public static final Collection<string> PRIMARY_COLORS = Arrays.asList("red", "yellow", "blue");
...
if ( PRIMARY_COLORS.contains(color) ) {System.out.println("This is a primary color");
}
final关键字可防止将PRIMARY_COLORS变量重新分配给另一个值集合-当将变量定义为public时,这一点尤其重要。 如果安全是主要问题,则还应将原始集合包装为不可修改的集合。 这将保证只读访问。
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;public static final Collection PRIMARY_COLORS =Collections.unmodifiableCollection( Arrays.asList("red", "yellow", "blue") );
必须注意,尽管更易读,但使用值的集合(尤其是大型集合)通常会比(而不是像)经典的惰性 OR(即使用'||'而不是' |'),因为存在短路 评估 。 我倾向于认为如今这种考虑是徒劳的。
经过16年的抱怨,Java 7终于有了! –在switch-case语句中引入了对String的支持。 这使我们可以编写如下代码:
boolean primary;
switch(color) {case "red":primary=true; break;case "green":primary=true; break;case "blue":primary=true; break; default:primary=false;
}
if (primary) System.out.println("This is a primary color");
让我们最后以解决我们(可以这么说)问题的最面向对象的解决方案作为结尾。 Java枚举主要是类,因此可以像其他任何类一样具有方法和字段。 通过应用Template Method设计模式 ,可以定义一种抽象方法(对测试进行建模),该方法必须由所有子类实现(对应用于枚举的特定项的测试响应进行建模):
Color c = Color.valueOf("RED");
if ( c.isPrimaryColor() ) {System.out.println("This is a primary color");
}public enum Color {RED() {@Override public boolean isPrimaryColor() {return true;}},BLUE() {@Override public boolean isPrimaryColor() {return true; }},YELLOW() {@Override public boolean isPrimaryColor() {return true; }};GREEN() {@Override public boolean isPrimaryColor() {return false; }};public abstract boolean isPrimaryColor();
}
生成的代码是清晰的并且具有自我说明性。 在许多情况下,使用此模式可以替代更常见的“ if – else if”逻辑,因为它更易于阅读,扩展和维护。
总而言之,我想说,对于一个问题,在很多情况下(就实现而言),存在着许多不同的解决方案,而这正是Java语言的强大功能。 但是,决定哪个最好是另一个故事……
参考: 简短但正确! 来自我们的W4G合作伙伴 Bernard Ligny 。
相关文章 :
- Java中的低GC:使用原语而不是包装器
- Java Lambda语法替代
- JVM如何处理锁
- Java Fork / Join进行并行编程
- Java最佳实践系列
- 如何在Java中获得类似于C的性能
翻译自: https://www.javacodegeeks.com/2011/09/do-it-short-but-do-it-right.html