瑞瑞哥的博客

和团子讨论一下代码

和团子讨论一下代码

只是个人简单的一点意见哈,有问题互相学习交流

源代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public static Script parsing() {
Script sc = new Script();
int ch;
try {
while((ch = fr.read()) != -1) {
zh+=(char)ch;
}
} catch (IOException e) {
e.printStackTrace();
}
char c;
for(int i = 0; i<zh.length(); i++) {
c = zh.charAt(i);
switch(c) {
case title :
sc.setTitle(zh.substring(i + 1, zh.indexOf(sperator)));
i = zh.indexOf(sperator);
break;
case author :
sc.setAuthor(zh.substring(i + 1, zh.indexOf(sperator, i)));
i = zh.indexOf(sperator, i);
break;
case sentences :
sc.addSentence(zh.substring(i + 1, zh.indexOf(sperator, i)));
i = zh.indexOf(sperator, i);
break;
case battle :
String copy = zh.substring(i + 1, zh.indexOf(sperator, i));
int a = copy.indexOf(battle_sperator),b;
int code = Integer.parseInt(copy.substring(0, a));
b = a + 1;
a = copy.indexOf(battle_sperator, a + 1);
String next = copy.substring(b, copy.indexOf(battle_sperator, a));
b = a + 1;
a = copy.indexOf(battle_sperator, a + 1);
String last = copy.substring(b, copy.indexOf(battle_sperator, a));
b = a + 1;
a = copy.indexOf(battle_sperator, a + 1);
String trigger_name = copy.substring(b, copy.indexOf(battle_sperator, a));
b = a + 1;
String target_name = copy.substring(b, copy.length());
Unit trigger = new Unit(trigger_name);
Unit target = new Unit(target_name);
sc.addBattle(code, next, last, trigger, target);
break;
}
}
return sc.finish();
}

数组越界

摘要片段如下:

1
2
3
4
5
6
7
8
9
10
for(int i = 0; i<zh.length(); i++) {
c = zh.charAt(i);
switch(c) {
case title :
sc.setTitle(zh.substring(i + 1, zh.indexOf(sperator)));
i = zh.indexOf(sperator);
break;
...
}
}

对于数组或者iterable(可循环)的类型,访问它的成员的时候一定要注意是否会越界访问。拿这个作为例子,如果当i为最后一位,即zh.length()-1时,恰好进入case的某个分支,调用zh.substring(i + 1, zh.indexOf(sperator)) ,即可造成数组越界,因为i已经是最后一个char了,没有i+1了。

To 团子:
你可能说,我的业务逻辑会保证“只有i不是最后一个字符的时候,才进入switch的分支”,如果是这样的话,确实不会造成i+1越界的问题,但是如果以后业务变更了,或者别人接手了就会发生问题。所以最好的方法就是在代码里保证不会数组越界,而不是用业务逻辑保证,这是个好习惯。

代码格式

在大块代码的时候,推荐加一些空行和注释让代码可读性更强,也推荐使用格式化代码的方法让代码格式更加规范。

关于空行

比如这一大段可以改成这样:

1
2
3
4
5
6
7
8
9
10
try {
while((ch = fr.read()) != -1) {
zh+=(char)ch;
}
} catch (IOException e) {
e.printStackTrace();
}
//这里可以考虑空一行,因为上下没什么太大关系
char c;
for(int i = 0; i<zh.length(); i++) {

代码格式化

如果用的是Eclipse,按CTRL + Shift + f就可以格式化你的java代码。其他IDE的话,快捷键可以去搜一下;有的比较轻量级的编辑器可能需要插件。

适当添加注释

很多时候自己的代码6个月之后就不认识了,没事可以添加一点注释。

关于case

1
2
switch(c) {
case title :

case后面跟的是常量,一般推荐使用大写来作为变量名,这样可读性强,而且不容易乱:

1
2
switch(c) {
case TITLE :

switch最好有个default

这个是个好习惯

关于变量命名

除了循环里的i,j,k等,尽量不要用a,b,c 等无意义的变量名(尤其是单字母的),尽管有的时候给它想一个名字很困难

面向对象

如果以后有机会重构,面向对象的思想还可以在运用一下,这样代码可读性、可维护性更强