新手常犯技术问题小结

新手常犯技术问题

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1.1 用类变量解决共享问题

由于类中的方法都可以修改类变量的值,那么使用类变量来解决函数间的数据共享问题就会出现可能的错误。

所以,要减少或避免使用类变量来解决问题,应该考虑用传递参数、函数返回值的办法。

  1. privateintcurrentNum;
  2. publicvoidprintCurrentNum(){
  3. methodA();
  4. methodB();
  5. }
  6. PrivatevoidmethodA(){
  7. currentNum=1;
  8. }
  9. PrivatevoidmethodB(){
  10. if(1==currentNum){
  11. System.out.println("Currentnumberis"+currentNum);
  12. }
  13. }
  1. publicvoidprintCurrentNum(){
  2. finalintcurrentNum=methodA();
  3. methodB(currentNum);
  4. }
  5. PrivateintmethodA(){
  6. return1;
  7. }
  8. PrivatevoidmethodB(intcurNum){
  9. if(1==curNum){
  10. System.out.println("Currentnumberis"+currentNum);
  11. }
  12. }

1.2

不给局部变量赋初值

不管是C#还是Java都会给类成员变量自动赋初值,但不会给局部变量赋初值,所以,如果要得到正确的结果,一定要给局部变量赋初值。

注:如果不给局部变量赋初值,Java编译器会报错。但不是所有的编译器都报错。

1.3 忽略返回值的判断

很多情况下,对返回值的判断决定程序下一步是否进行。所以,一定要注意返回值的判断。

方法methodA已经给出了系统错误的情况,但由于没有对其返回值进行判断,导致程序最终给出了错误的结论。

public void printSystemState() {

methodA();

methodB();

System.out.println("System is normal.");

}

private boolean methodA() {

System.out.println("System error.");

return false;

}

private void methodB() {

}

该例中方法methodB会抛出NullPointerException,是由于没有对methodA的返回值进行有效性判断。

public void judgeString() {

final String str = methodA();

methodB(str);

}

private String methodA() {

return null;

}

private void methodB(String str) {

if(str.equals("test")) {

System.out.println("The string input is test.");

}

}

1.4 变量或函数命名不准确

变量或函数的命名要符合变量或函数所代表的意义,直观的讲,就是让读者一看就知道变量或者函数的用途。

1.5 字符串的比较equals

如果字符串和一个常量字符串进行比较,常量字符串应该放在前面。如果两个非常量字符串进行比较,要确认前面的字符串不是null.

如下的代码则会抛出NullPointerException类型的异常。

private void methodB(String str) {

if(str.equals("test")) {

System.out.println("The string input is test.");

}

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shape id="_x0000_s1027" style="MARGIN-TOP: 1.55pt; Z-INDEX: 2; MARGIN-LEFT: 221.4pt; WIDTH: 36pt; POSITION: absolute; HEIGHT: 27pt" strokecolor="green" fillcolor="blue" type="#_x0000_t67"><textbox style="LAYOUT-FLOW: vertical-ideographic"></textbox></shape>}

private void methodB(String str) {

if("test".equals(str)) {

System.out.println("The string input is test.");

}

}

1.6 关键步骤缺少必要的注释

常常一个方法的实现没有一行注释,开发者在编写的时候应该在一些关键步骤添加必要的解释,以方便读者的阅读和理解,同时对开发者本身来讲,将来修改代码的时候也容易记起当时的想法。

1.7 用一次或几次测试来判断代码的正确性

常常听开发者讲,这个方法我测了几遍,没有问题。这个方法的实现果真没有问题吗?

开发者本身的测试常常会集中在正常流程的情况下,而对于一些边界情况、异常情况则很少在意。再者,这种随机的测试也不能保证正确性。

代码的正确首先要从设计、逻辑这方面保证,然后在通过严格的测试来保证代码的正确性。

当然,有些运行很稳定的代码不一定就是正确的,只是现有的情况还没有命中代码的缺陷。

1.8 忘记关闭已打开的文件

虽然一些高级语言,例如C#Java都会对内存进行管理,开发者不用担心内存操作的复杂性,但是对于文件的操作却都没有提供安全的管理。

也就是说,文件的操作一定要开发者自己来处理,打开的文件一定要自己关闭。

对于Java来讲,可以通过Findbugs来发现文件操作潜在的问题。

下边这个例子就没有成功的关闭文件。一旦在inStream读取的时候发生异常,两个打开的文件都不能正确的关闭。这时候可以考虑使用finally来关闭文件。

public boolean copyFile(String srcPath, String destPath) {

boolean result = false;

// check source whether exist

final File oldfile = new File(srcPath);

if (!oldfile.exists()) {

return result;

}

InputStream inStream = null;

OutputStream outStream = null;

try {

inStream = new FileInputStream(srcPath);

outStream = new FileOutputStream(destPath);

final byte[] buffer = new byte[1024];

int bytesRead = 0;

while ((bytesRead = inStream.read(buffer)) != -1) {

outStream.write(buffer, 0, bytesRead);

}

inStream.close();

outStream.close();

result = true;

} catch (IOException e) {

}

return result;

<shape id="_x0000_s1028" style="MARGIN-TOP: 1.95pt; Z-INDEX: 3; MARGIN-LEFT: 324.55pt; WIDTH: 36pt; POSITION: absolute; HEIGHT: 27pt" strokecolor="green" fillcolor="blue" type="#_x0000_t67"><textbox style="LAYOUT-FLOW: vertical-ideographic"></textbox></shape>}

public boolean copyFile(String srcPath, String destPath) {

boolean result = false;

// check source whether exist

……

InputStream inStream = null;

OutputStream outStream = null;

try {

……

result = true;

} catch (IOException e) {

} finally {

try {

if (null != inStream) {

inStream.close();

}

if (null != outStream) {

outStream.close();

}

} catch (IOException e) {

}

}

return result;

}

1.9 嵌套过深

曾经见过六层if嵌套的代码,试想这样的代码看起来有多费劲。所以,要减少嵌套过深的代码。

private String methodA() {

if (a) {

if (b) {

if (c) {

if (d) {

System.out.println("abcd");

}

}

}

}

<shape id="_x0000_s1029" style="MARGIN-TOP: 5.85pt; Z-INDEX: 4; MARGIN-LEFT: 212.4pt; WIDTH: 36pt; POSITION: absolute; HEIGHT: 27pt" strokecolor="green" fillcolor="blue" type="#_x0000_t67"><textbox style="LAYOUT-FLOW: vertical-ideographic"></textbox></shape>}

private String methodA() {

if (a && b && c && d) {

System.out.println("abcd");

}

}

1.10 测试代码缺少assert

往往测试代码的要求在于测试覆盖率要达到多少,而没有assert语句的测试代码对于覆盖率没有任何影响,但assert语句却对测试代码有很重要的作用,它反应测试代码的正确性。

例如有如下方法,返回字符串test

private String methodA() {

return "test";

}

该测试方法虽然调用了methodA方法,测试覆盖率也100%,但却没有验证methodA的正确性。

public void testMethodA() {

methodA();

}

使用assert来验证方法的返回值。

public void testMethodA() {

String str = methodA();

assertEquals(str, "test");

}

1.11 不清理建立的测试文件夹或文件

在测试代码中,经常会有一些为了测试建立的文件夹或文件,如果不注意删除。那么就可能在测试者机器上出现无用的文件夹或文件。

在测试代码中要注意清理这些无用的东西。

public void testMethodA() {

final String outputDir = "./main/test/out/";

FileOperator.createFolder(outputDir); // create folder for test

…… // test code

FileOperator.deleteFiles(outputDir); // delete test folder

}

你可能感兴趣的:(技术)