标题由来:
比来在一个java bean类中界说了一个boolean类型的变量:
//boolean属性:是不是显现
private boolean isShowCode ;
//应用Eclipse主动天生getter/setter方式以下:
public boolean isShowCode() {
return isShowCode;
}
public void setShowCode(boolean isShowCode) {
this.isShowCode = isShowCode;
}
spring在给java bean 设置值的时辰, 抛出异常:
Caused by: org.springframework.beans.NotWritablePropertyException:
Invalid property isShowCode of bean class [com.codemouse.beans.Country]:
Bean property isShowCode is not writable or has an invalid setter method.
Did you mean showCode ?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1064)
代码运转状况: jdk 1.6 + eclipse 3.2 + spring 3.1, 本文上面的代码都在该状况下测试。
缘由跟踪阐发:跟踪Spring源码, 能够看到上面这段代码:
private CachedIntrospectionResults(Class beanClass,
boolean cacheFullMetadata) throws BeansException {
... ...
this.beanInfo = new ExtendedBeanInfo(Introspector.getBeanInfo(beanClass));
... ...
}
方式Introspector.getBeanInfo(beanClass)前往的时辰,取得到的java bean 信息中的isShowCode属性的称号已被改成了 showCode 。
到这里能够肯定标题不是出在spring代码中, 网上有很多帖子说是spring的处置规律致使了这个标题,这里能否是能够承认这类观念?
标题跟踪到这,也即跟踪到了java.beans包。检验考试连续跟踪JDK源码,可以由于我的JDK的jar包和源码不婚配的缘由, eclipse老是监控不到中心变量。也就没有再跟踪出来了。能够明白的是,javabean中 的isShowCode 属性 和 对应的getter/setter方式应当是没有恪守javabean规范。Eclipse主动天生的getter/setter方式看来也是存在一些标题的。
Eclipse主动天生boolean类型属性的方式能否是有点奇特呢? 属性 isShowCode 的getter拜候器是isShowCode()而不是getIsShowCode(), setter设值器是setShowCode()而不是setIsShowCode()。原本在java bean 规范关于中提到, boolean属性 propertyName 的getter拜候器可运用上面这类方式
public boolean is PropertyName (){...};
来取代
public boolean get PropertyName (){...};
Javabean 规范(下载链接://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/ ) 在8.3 章节 Design Patterns for Properties 中的描写:
Eclipse依照这类格式天生getter拜候器和setter设值器, 由于属性名isShowCode的is没有往失落, 乃至java bean类背背了java bean 的定名规范。
JavaBean 的属性名和getter/setter存取方式规律小结:
1. 对惯例属性 propertyName , 属性称号的第一个单词小写且字母个数大于1,第二个单词首字母大写 。对应的getter/setter方式名为:get /set + PropertyName (), 即属性称号的第一个单词的首字母改成大写, 后面再加上 get 或 set 前缀。
2. 对布尔类型 propertyName , 能够按惯例属性的规律编写getter/setter方式外, getter方式可运用 is + PropertyName ()的形势来取代。
3. 对很是规属性 pName , 属性称号的第一个单词小写且字母个数即是1,第二个单词首字母大写 。
3.1 ) 对应的getter/setter方式名可觉得:get/set + PName (), 即第一个单词的首字母为改成大写,后面再加上 get 或 set 前缀。Eclipse3.2 按这类格式主动天生getter/setter方式。代码片断:
bean id= country >
property name= pName
value 中国 /value
/property
property name= code
value CN /value
/property
property name= showCode
value true /value
/property
/bean
private String pName;
public String getPName() {
return pName;
}
public void setPName(String name) {
pName = name;
}
3.2 )对应的getter/setter方式名也可以为:get/set+ pName (), 即属性称号不变,第一个单词的首字母任然为小写,后面再加上 get 或 set 前缀。这类格式也可以正常运转。网上有帖子说Eclipse3.5按这类格式主动天生getter/setter方式。
代码片断:
bean id= country >
property name= pName
value 中国 /value
/property
property name= code
value CN /value
/property
property name= showCode
value true /value
/property
/bean
private String pName;
public String getpName() {
return pName;
}
public void setpName(String name) {
pName = name;
}
4. 对很是规属性 PName , 属性称号的前两个字母都是大写 。即持续两个大写字母开首的属性名。
对应的getter/setter方式名为: get/set + PName (), 即属性称号不变,后面再加上 get 或 set 前缀。
spring3.1 设置配备摆设文件代码片断:
bean id= country >
property name= PName
value 中国 /value
/property
property name= code
value CN /value
/property
property name= showCode
value true /value
/property
/bean
private String PName;
public String getPName() {
return PName;
}
public void setPName(String name) {
PName = name;
}
5. 对很是规属性 Property 或 PropertyName , 属性称号第一个字母大写 。网上有帖子说这是不适宜JSR规范的,会报 属性找不到 的缺点。
(如帖子1: //lzh166.iteye.com/blog/631838 ;
帖子2: //hi.百度.com/w8y56f/blog/item/4fd037e845bbbe372cf5342a.html)。我在我的 状况下测试了下, 是不会报错的,能够正常运转,固然这类定名格式是使人难以忍受的:
bean id= country >
property name= PropertyName
value 中国 /value
/property
property name= code
value CN /value
/property
property name= showCode
value true /value
/property
property name= Xcoordinate
value 12.345 /value
/property
/bean
private String PropertyName;
public String getPropertyName() {
return PropertyName;
}
public void setPropertyName(String propertyName) {
PropertyName = propertyName;
}
private Double Xcoordinate;
public Double getXcoordinate() {
return Xcoordinate;
}
public void setXcoordinate(Double xcoordinate) {
Xcoordinate = xcoordinate;
}
测试方式: 第一个@test方式用浅显javabean挪用格式测试; 第二个@test方式应用spring树立bean
@Test
public void testJavaBeanNamingRule0(){
Country country = new Country();
country.setPropertyName( 中国 );
country.setXcoordinate(Double.valueOf(123.456f));
System.out.println(country.getPropertyName());
System.out.println(country.getXcoordinate());
}
@Test
public void testJavaBeanNamingRule(){
ApplicationContext ctx = new ClassPathXmlApplicationContext( myBeans.xml );
Country country = (Country)ctx.getBean( country );
System.out.println(country.getPropertyName());
System.out.println(country.getXcoordinate());
}
运转成果:都能够正常运转。
中国
123.45600128173828
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
中国
12.345
总结:
1. javabean属人命名尽可能应用惯例的驼峰式定名规律
2. 属性名第一个单词尽可能避免应用一个字母:如eBook, eMail。
3. boolean属性名避免应用 “is” 开首的称号
4. 跟着jdk, eclipse, spring 等软件版本的不竭进步, 底版本的呈现的标题可以在高版本中处置了, 低版来源根基来正常的代码可以在高版本状况下不再支撑。