org.apache.commons.beanutils是我們經常會用到工具包,其中的describe方法可以將對象的所有可讀屬性和對應值放入Map中返回給我們,下面的代碼片段由qdcrm系統中的線上代碼轉化而來:
public class ObjA {
public String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public Map getProperty() {
try {
return (BeanUtils.describe(this));
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
return null;
}
}
你看出這段代碼有什麼問題了嗎?
下面我們來分析一下:
當我們對ObjA的一個實例調用getProperty()方法的時候,首先describe方法會通過PropertyUtilsBean.getPropertyDescriptors()獲取ObjA的所有屬性,而該方法會通過查看一個屬性是否有getter或setter來判斷這個屬性是否存在,也就是說,如果存在方法void setXXX(XXX xxx)或者方法XXX getXXX()則他就會認爲這個類包含屬性XXX。那麼現在程序拿到的ObjA屬性列表將是[a,class,property],既然得到了屬性列表,那接下來便要根據屬性列表去獲取對應屬性的值了,這時程序將調用每個屬性對應的get方法去獲取屬性的值,於是getProperty方法又被調用了,這裏便出現了循環調用,會導致棧溢出錯誤。
解決的辦法很簡單,我們只要將getProperty換一個方法名即可,比如叫做property()。