新手常犯技术问题小结

新手常犯技术问题

1.1         用类变量解决共享问题

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

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

  1. private int currentNum;
  2. public void printCurrentNum() {
  3.      methodA();
  4.      methodB();
  5. }
  6. Private void methodA() {
  7.      currentNum = 1;
  8. }
  9. Private void methodB() {
  10.      if (1 == currentNum) {
  11.            System.out.println("Current number is " + currentNum);
  12.      }
  13. }
  1. public void printCurrentNum() {
  2.      final int currentNum = methodA();
  3.      methodB(currentNum);
  4. }
  5. Private int methodA() {
  6.      return 1;
  7. }
  8. Private void methodB(int curNum) {
  9.      if (1 == curNum) {
  10.            System.out.println("Current number is " + 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.");

     }

}

 

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;

}

 

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");

                     }

                }

           }

     }

}

 

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

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值