Java中的字段和属性到底是什么?他们的含义真的是相同的吗?如果不同,那他们到底又分别是何含义呢?

相信上面的问题,对于很多Java初学者都是相当困惑的,但是好像把他们理解为一个含义也没啥问题,很多Javaer也就这么放过这个问题了,但是遇到如下两个问题,你能正确解决并给出问题出现的原因吗?

先给出如下的一个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;
}
}

问题一

假设我们现在要在spring的配置文件中配置上述JavaBean的一个实例,如下。暂时不设置除Id外其他属性值。

当我们启动spring容器时,我们将得到如下错误,这个错误具有很强的误导性,明明类中定义了aGe,也提供了setter方法,为什么报错说找不到?

问题二

在使用JSP的时候,页面返回ModelAndView,且返回一个UserInfo实例类,在JSP页面中使用isCool时,页面报错说找不到,或者返回json数据时。

企业微信截图_0bb7396f-fbb9-4296-8a99-b5fc7957d44d.png

解决方案

很多有经验的Javaer对于上述两个问题都能很好的解决,但很少有人能给出问题出现的原因。这里我们也先给出这两个问题的解决方案,之后再给出问题出现的原因。

字段名的前两个字母要么全大写,要么全小写

boolen类型的字段不要以is开头(这里阿里巴巴的开发者手册也重点强调了)

问题出现的原理

对于这两个问题出现的原理,归根结底就是开发者对于Java中字段和属性的含义模糊不清导致的。

字段

Java中字段的含义就是Java类中定义的成员变量,可以通过Java的反射机制获取所有的字段名,Class#getFields()方法或者Class#getDeclaredFields()方法,这里可以看出field其实就是字段的意思。

属性

Java中的属性,其实是相对于JavaBean来说的。所以在Java中,正确的说法应该是JavaBean中有XXX属性,Java类中有OOO字段或成员变量。属性的英文翻译是property

BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
System.out.println(propertyDescriptor.getName());
}

如上代码就会输出UserInfo类对应的JavaBean的所有属性名

输出结果

可以看出一共有class、cool、dizhi、id四个属性,其中class属性我们暂时先不管。在XML中的配置或者JSP页面以及JSON序列化,其实都是使用的JavaBean的属性,而不是Java中定义的字段。那么对于前面说的两个问题也就很容易解释了。对于问题一,我们在XML中配置了iD值,但JavaBean中确实是没有这个属性的,只有id属性。对于问题二也是一样,JavaBean中只有cool属性。

总结

在Java中很少有直接操作类字段的情况,大部分都是操作JavaBean的属性,所以要了解好属性名的规则,牢记上面的解决方案,真不小心遇到问题,知道了背后的原理,相信也会很容易解决的。

JavaBean的属性名其实就是Java类中定义的setter或者getter方法名,去掉set或者get或者is得到的字符串,判断首字母是否是小写,如是,则该字符串就是属性名,否则再判断第二个字母是否是大写,如是,则该字符串就是属性名,否则将首字母小写得到的名称就是属性名,比如getDizhi()方法属性名就是dizhi,getdizhi()方法属性名也是dizhi,getdIzhi()方法属性名就是dIzhi,getDIzhi()方法属性名就是DIzhi,其中bool类型的属性的get方法名不是以get开头,而是以is开头。对于只有get或者只有set方法的属性,我们就说他是只读或只写属性。之所以规定Java的字段定义不准以is开头且首两个字母要么都大写要么都小写,就是为了让JavaBean的属性名与字段名一致,这样对于初学者就不会造成一定的困惑,即是不了解也能正常使用。