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會記住之前的内容。這也就是産生有狀态的根源。
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;
}
public boolean accept(File arg0, String arg1) {
}}, new IOFileFilter(){
@Override
public boolean accept(File arg0) {
// TODO Auto-generated method stub
return true;
}
public boolean accept(File arg0, String arg1) {
}} );
return files;
}
總結:
1、大膽的猜測,對問題的原因有基本的分析
2、Debug非常重要,有了基本的分析之後,啟動debug進行跟蹤,小心的求證,不要在之前猜測之外再去做胡亂的猜想。Debug是硬本領,一定要精通。
3、對基礎類,寫代碼的時候一定要仔細再仔細,測試了再測試
4、多學習優秀的開源實作,例如apache、spring等開源社群的代碼
本文轉自 tianya23 51CTO部落格,原文連結:http://blog.51cto.com/tianya23/664672,如需轉載請自行聯系原作者