panama项目,近期在完成基于eclipse插件的开发。在集成测试中发现,每次在执行tocase功能的过程中,本次记住了之前tocase的执行内容(会再次执行之前tocase的内容)。第一反应:程序中存在有状态的代码,例如static,这个反应最后证明也是正确的。
调试分析:在eclipse中使用debug的方式启动eclipse插件程序(导入:import-> plug-ins and Fragments -> Directory选择eclipse插件项目;debug启动:plugin.xml -> debug as -> Eclipse Application)。发现问题发生在FileUtils类中获取目录以及子目录下面的所有文件,核心部分基本示意如下:
- static List<String> fileNameList = new ArrayList<String>();
- public static List<String> readfile(String filepath) throws FileNotFoundException, IOException {
- try {
- File file = new File(filepath);
- if (!file.isDirectory()) {
- fileNameList.add(file.getName());
- } else if (file.isDirectory()) {
- String[] filelist = file.list();
- for (int i = 0; i < filelist.length; i++) {
- File readfile = new File(filepath + "\\" + filelist[i]);
- if (!readfile.isDirectory()) {
- fileNameList.add(readfile.getName());
- } else if (readfile.isDirectory()) {
- readfile(filepath + "\\" + filelist[i]);
- }
- }
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- System.out.println("readfile() Exception:" + e.getMessage());
- }
- return fileNameList;
- }
这么简单直接的代码会有什么问题吗?确实有问题,它是有状态的。 当在同一个JVM里面多次调用的时候,fileNameList会记住之前的内容。这也就是产生有状态的根源。
思考之后,发现递归是不能解决问题的,因为针对方法readfile的直接调用和递归调用对程序来说没有差别,也就意味着无法决定是什么时候重置fileNameList 的内容。思考之后阅读了apache io的代码,简单使用了一下,问题解决了。帮助文档:http://commons.apache.org/io/api-release/index.html?org/apache/commons/io/FileUtils.html,示例代码如下:
- public static Collection<File> readfile1(String filepath) throws FileNotFoundException, IOException {
- Collection<File> files = org.apache.commons.io.FileUtils.listFiles(new File(
- filepath), new IOFileFilter(){
- @Override
- public boolean accept(File arg0) {
- // TODO Auto-generated method stub
- return true;
- }
- @Override
- public boolean accept(File arg0, String arg1) {
- // TODO Auto-generated method stub
- return true;
- }}, new IOFileFilter(){
- @Override
- public boolean accept(File arg0) {
- // TODO Auto-generated method stub
- return true;
- }
- @Override
- public boolean accept(File arg0, String arg1) {
- // TODO Auto-generated method stub
- return true;
- }} );
- return files;
- }
总结:
1、大胆的猜测,对问题的原因有基本的分析
2、Debug非常重要,有了基本的分析之后,启动debug进行跟踪,小心的求证,不要在之前猜测之外再去做胡乱的猜想。Debug是硬本领,一定要精通。
3、对基础类,写代码的时候一定要仔细再仔细,测试了再测试
4、多学习优秀的开源实现,例如apache、spring等开源社区的代码
本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/664672,如需转载请自行联系原作者