Java中的字段和屬性到底是什么?他們的含義真的是相同的嗎疾嗅?如果不同外厂,那他們到底又分別是何含義呢?
相信上面的問題代承,對(duì)于很多Java初學(xué)者都是相當(dāng)困惑的汁蝶,但是好像把他們理解為一個(gè)含義也沒啥問題,很多Javaer也就這么放過這個(gè)問題了论悴,但是遇到如下兩個(gè)問題掖棉,你能正確解決并給出問題出現(xiàn)的原因嗎?
先給出如下的一個(gè)JavaBean
public class UserInfoVo {
private boolean isCool;
private String Name;
private String aGe;
private String BIrthday;
private String address;
public String getaddress() {
return address;
}
public void setaddress(String address) {
this.address = address;
}
public boolean isCool() {
return isCool;
}
public void setCool(boolean cool) {
isCool = cool;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getaGe() {
return aGe;
}
public void setaGe(String aGe) {
this.aGe = aGe;
}
public String getBIrthday() {
return BIrthday;
}
public void setBIrthday(String BIrthday) {
this.BIrthday = BIrthday;
}
}
問題一
假設(shè)我們現(xiàn)在要在spring的配置文件中配置上述JavaBean的一個(gè)實(shí)例膀估,如下幔亥。暫時(shí)不設(shè)置除Id外其他屬性值。
<bean id="userInfo" class="com.dfz.UserInfoVo">
<property name="aGe" value="xxxxxxxx"/>
</bean>
當(dāng)我們啟動(dòng)spring容器時(shí)察纯,我們將得到如下錯(cuò)誤帕棉,這個(gè)錯(cuò)誤具有很強(qiáng)的誤導(dǎo)性,明明類中定義了aGe饼记,也提供了setter方法香伴,為什么報(bào)錯(cuò)說(shuō)找不到?
問題二
在使用JSP的時(shí)候握恳,頁(yè)面返回ModelAndView瞒窒,且返回一個(gè)UserInfo實(shí)例類,在JSP頁(yè)面中使用isCool時(shí)乡洼,頁(yè)面報(bào)錯(cuò)說(shuō)找不到,或者返回json數(shù)據(jù)時(shí)匕坯。
解決方案
很多有經(jīng)驗(yàn)的Javaer對(duì)于上述兩個(gè)問題都能很好的解決束昵,但很少有人能給出問題出現(xiàn)的原因。這里我們也先給出這兩個(gè)問題的解決方案葛峻,之后再給出問題出現(xiàn)的原因锹雏。
- 字段名的前兩個(gè)字母要么全大寫,要么全小寫
- boolen類型的字段不要以is開頭(這里阿里巴巴的開發(fā)者手冊(cè)也重點(diǎn)強(qiáng)調(diào)了)
問題出現(xiàn)的原理
對(duì)于這兩個(gè)問題出現(xiàn)的原理术奖,歸根結(jié)底就是開發(fā)者對(duì)于Java中字段和屬性的含義模糊不清導(dǎo)致的礁遵。
字段
Java中字段的含義就是Java類中定義的成員變量轻绞,可以通過Java的反射機(jī)制獲取所有的字段名,Class#getFields()
方法或者Class#getDeclaredFields()
方法佣耐,這里可以看出field其實(shí)就是字段的意思政勃。
屬性
Java中的屬性,其實(shí)是相對(duì)于JavaBean來(lái)說(shuō)的兼砖。所以在Java中奸远,正確的說(shuō)法應(yīng)該是JavaBean中有XXX屬性,Java類中有OOO字段或成員變量讽挟。屬性的英文翻譯是property
BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
System.out.println(propertyDescriptor.getName());
}
如上代碼就會(huì)輸出UserInfo類對(duì)應(yīng)的JavaBean的所有屬性名
可以看出一共有class懒叛、cool、dizhi耽梅、id四個(gè)屬性薛窥,其中class屬性我們暫時(shí)先不管。在XML中的配置或者JSP頁(yè)面以及JSON序列化眼姐,其實(shí)都是使用的JavaBean的屬性拆檬,而不是Java中定義的字段。那么對(duì)于前面說(shuō)的兩個(gè)問題也就很容易解釋了妥凳。對(duì)于問題一竟贯,我們?cè)赬ML中配置了iD值,但JavaBean中確實(shí)是沒有這個(gè)屬性的逝钥,只有id屬性屑那。對(duì)于問題二也是一樣,JavaBean中只有cool屬性艘款。
總結(jié)
在Java中很少有直接操作類字段的情況持际,大部分都是操作JavaBean的屬性,所以要了解好屬性名的規(guī)則哗咆,牢記上面的解決方案蜘欲,真不小心遇到問題,知道了背后的原理晌柬,相信也會(huì)很容易解決的姥份。
JavaBean的屬性名其實(shí)就是Java類中定義的setter或者getter方法名,去掉set或者get或者is得到的字符串年碘,判斷首字母是否是小寫澈歉,如是,則該字符串就是屬性名屿衅,否則再判斷第二個(gè)字母是否是大寫埃难,如是鉴扫,則該字符串就是屬性名园蝠,否則將首字母小寫得到的名稱就是屬性名,比如getDizhi()
方法屬性名就是dizhi
,getdizhi()
方法屬性名也是dizhi
涯贞,getdIzhi()
方法屬性名就是dIzhi
,getDIzhi()
方法屬性名就是DIzhi
,其中bool類型的屬性的get方法名不是以get開頭热监,而是以is開頭展姐。對(duì)于只有g(shù)et或者只有set方法的屬性矾飞,我們就說(shuō)他是只讀或只寫屬性。之所以規(guī)定Java的字段定義不準(zhǔn)以is開頭且首兩個(gè)字母要么都大寫要么都小寫座泳,就是為了讓JavaBean的屬性名與字段名一致惠昔,這樣對(duì)于初學(xué)者就不會(huì)造成一定的困惑,即是不了解也能正常使用挑势。