发布时间: 2017-06-16 14:22:24
作为一名IT培训讲师,我的工作就是不断审查学生们编写的代码。
这里我不想取笑任何人,单纯希望大家能够从中获得启示。我们先看一个奇妙的例子:
if(a<8&&b<8&&c<8)
a = 8;b=8;c=8;
大家不妨看看其中的错误在哪。大家发现了多少问题?我们先对其进行分析。最惹眼的肯定是“if”的密度。其中的三项条件之间没有用空格隔开。由于&运算符跟8相邻,因此很容易让人看花眼。大家最好在代码内容间加上空格,包括各语句之间、运算符之前与之后。下面我们对其进行重写:
if(a < 8 && b < 8 && c < 8)
有过编程经验的朋友对“魔数”肯定有着深刻印象。魔数是指那些直接出现在代码当中,不会自我描述且对于阅读者而言毫无意义的数字。如果大家对于“8”这个数字没有什么特别的负面感觉,那可以肯定您的编程从业时间并不长。这里欢迎大家来猜猜这个数字的含义。由于正是本人给学生们布置的作业,所以我很清楚这里“8”的意义(代表的是工人下班的最早时间),但对他人来说则很难猜。更糟糕的是,数字“8”在这段代码中重复编写了6次,意味着如果我们要将其换成7,则需要多次修改并反复查看以确认没有漏掉某个“8”。解决方案当然是使用常量。这里我们可以定义一条常量:
finalint EARLIEST_HOUR = 8;
现在代码变成了这样:
if(a < EARLIEST_HOUR && b < EARLIEST_HOUR && c < EARLIEST_HOUR)
a = EARLIEST_HOUR; b = EARLIEST_HOUR; c = EARLIEST_HOUR;
接下来看看代码中的语义,这段代码到底要实现什么效果?现在有了常数,看起来应该更为清楚。“if”负责测试三个变量,a、b与c。如果三个变量的值全面小于8,则全部获得最早时间值分配。这类测试非常常见且能够防止非法输入状况。然而,让我们再来看看if本体——如果条件为真,哪行代码会执行if结果?在开始之前,我们首先要强调一点,Java是会直接忽略空格的。这意味着对编译器而言,我们可以随意使用空格但并非强制性。这同时意味着Java中的语句会在编译器发现“;”符号时终止,而非在行末自动终止。现在再来看看以上代码。其全部写在一行当中。由于这位同学在行前加了个“tab”,因此可以确定这一行属于“if”语句。那么问题仍来了,if的本体究竟是什么?if的本体是:
if(a < EARLIEST_HOUR && b < EARLIEST_HOUR && c < EARLIEST_HOUR)
a = EARLIEST_HOUR; b = EARLIEST_HOUR; c = EARLIEST_HOUR;
就是这样,只有“a”属于条件本体。那么语句剩下的部分呢?它们对于“if”毫无意义,意味着其无论条件是否为真都会被执行。如果这位学生认为条件为真时三项分配会被全部执行,那他就犯下了一个严重的逻辑错误,代码不可能实现这样的效果,但却很难看得出现。另外,我们还发现了另外两个问题:
1.条件为真时只有一次分配能够切实执行,而这与程序员的预期不符。
2.将太多语句写进同一行是种坏习惯。这并不是错误,Java允许这种作法,但其会干扰我们的审查与判断。
下面来看正确的代码编写方式:
if(a < EARLIEST_HOUR && b < EARLIEST_HOUR && c < EARLIEST_HOUR) {
a = EARLIEST_HOUR;
b = EARLIEST_HOUR;
c = EARLIEST_HOUR;
}
总体来讲这里列举的代码示例非常糟糕,其中包含大量问题且令程序员很难发现其中的错误。我的建议是作为刚刚入门的程序员,大家应当编写结构更为清晰且简洁的代码、正确使用空格、常量与缩进等元素。下面我们再来聊几个大家可能感兴趣的后续问题:
▶在最后的代码示例中,我利用该条件的本体包含了三个语句。我们该如何继续使用单行语句编写三次分配?如果不使用括号又该如何实现?
▶我提到“8”是个无法解释的“魔数”,但我并没有提到该变量的名称。这种命名方式是否也有问题?
▶如果a、b或者c中仅有一个变量的值小于8,结果会如何?