关于JavaBean规范的有关问题
(1)JavaBean 类必须是一个公共类,并将其访问属性设置为 public ,如: public class user{......}
(2)JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器
(3)一个javaBean类不应有公共实例变量,类变量都为private ,如: private int id;
(4)属性应该通过一组存取方法(getXxx 和 setXxx)来访问,一般是IDE(Eclipse、JBuilder) 为属性生成getter/setter 方法
一般JavaBean属性以小写字母开头,驼峰命名格式,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。例如:属性名为userName,其对应的getter/setter 方法是 getUserName/setUserName。
但是,还有一些特殊情况:
1、如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。
2、如果前两个字母是大写(一般的专有名词和缩略词都会大写),也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为URL,方法是getURL/setURL。
3、如果首字母大写,也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,方法是getName/setName,这种是最糟糕的情况,会找不到属性出错,因为默认的属性名是name。
所以在JavaBean命名时应该注意符合以上命名规范。
我们在写程序的时候,get和set方法一般是IDE工具自动生成的,所以上面这几种特殊情况,IDE工具不会帮我们特殊处理,所以在给属性命名时,属性变量的前两个字母一般要么全部大写,要么全部小写。下面是我遇到的情况:
public class Question { private int questionId; int[] qValue1 = new int[4]; String[] qValue2 = new String[6]; int[] qValue3 = new int[20]; int[] qValue4 = new int[4]; int[] rValue = new int[20]; //get和set方法省略...... }
在前台的jsp页面中用EL表达示${question.qValue1}取值的时候就会报
org.apache.jasper.el.JspPropertyNotFoundException:
的错误,规范有时大家可能不当回事,可是你如果没有遵守它,要付出代价啊,上面程序只要把属性名称改了,就能运行正常了。
cysunc对这个问题做了深入研究,下文转自http://chanson.iteye.com/blog/419028
1、背景
本文讲的普通JavaBean只是一个拥有Property(域/类变量)及其setter/getter的普通Java类。
有一定Java开发经验的人可能会知道,普通JavaBean的Property(域/类变量)的命名不能采用以下形式:aA***或者 Aa***,如:"aDdress"或"Address",否则,在web应用中会报无法找到这个Property(因为根据"规则",需要找的 是"ADdress"或"address")。但对于其中的原因,一般人都不明白,难道这是Sun公司当初定的规范吗?
Java开源以后,我们终于可以解开其中的谜:
2、普通JavaBean处理涉及到相关类
在web应用中,Servlet容器或者EJB容器一般会使用java.beans包中的类来加载这些JavaBean。
BeanInfo(接口)
|
SimpleInfo(类)
|
GenericBeanInfo(类)
GenericBeanInfo是JavaBean数据装载类。
Introspector是JavaBean处理中最重要的一个处理类。
另外的一些辅助类,就不一一列举了。
3、解密
3.1 开始
在应用中,我们通常会用以下代码来获取一个普通JavaBean相关的信息:
BeanInfo mBeanInfo = null; try { mBeanInfo = Introspector.getBeanInfo(Person.class); } catch (IntrospectionException e) { e.printStackTrace(); }
3.2 深入
在Introspector类的getBeanInfo方法中,我们发现其中与Property处理相关的行:
private GenericBeanInfo getBeanInfo() throws IntrospectionException { …… PropertyDescriptor apropertydescriptor[] = getTargetPropertyInfo(); …… }
3.3 继续深入
在Property处理方法中,我们发现其处理方式是根据getter/setter的方法来得到Property(域/类变量)
private PropertyDescriptor[] getTargetPropertyInfo() throws IntrospectionException{ …… if(s.startsWith("get")) obj = new PropertyDescriptor(decapitalize(s.substring(3)), method, null); …… }
3.4 关键
接下来,最关键的就是下面这个方法:
public static String decapitalize(String s) { if(s == null || s.length() == 0) //空处理 return s; if(s.length() > 1 && Character.isUpperCase(s.charAt(1)) && Character.isUpperCase(s.charAt(0))){ //长度大于1,并且前两个字符大写时,返回原字符串 return s; } else{ //其他情况下,把原字符串的首个字符小写处理后返回 char ac[] = s.toCharArray(); ac[0] = Character.toLowerCase(ac[0]); return new String(ac); } }
4 Ending
解密完成。
明白真相,才会解开心中的锁——其实很简单。