**我们一路奋战,不是为了改变世界,而是为了不让世界改变我们。**
-
运行环境
JDK8 + IntelliJ IDEA 2018.3
-
本文中使用的jar包链接
https://files.cnblogs.com/files/papercy/jsoup_jar%E5%8C%85.rar
-
JAVA Bean
1、了解JAVA Bean:
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。
2、Java Bean 的属性
JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
setId()的属性名àid
isLast()的属性名àlast
setCPU的属性名: CPU
getUPS的属性名: UPS
总之,一个类被当作JavaBean使用时类,JavaBean的属性是根据方法名推断出来的,它根本看不到java内部的成员变量。
3、使用Java Bean 的好处
- 在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作。
- JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过get X方法来访问私有的x,怎么做,有一定难度吧?用内省这套API操作JavaBean比用普通类的方式更方便
-
自动生成Reflect Point类的setter和getter方法
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
Object retVal = getProperty(pt1);
System.out.println(retVal);
PropertyDescriptor pd2 = null;
String propertyName = "y";
Object value = 7;
setProperty(pt1, propertyName, value);
//先通过调用普通java类的方法的方式获得结果,然后在这之前插入BeanUtil的get和set操作,见下面的代码。
//System.out.println(pt1.getY());
System.out.println(BeanUtils.getProperty(pt1, "y"));
BeanUtils.setProperty(pt1, "y", "99");
System.out.println(pt1.getY());
PropertyUtils.setProperty(pt1, "y", 999);
System.out.println(PropertyUtils.getProperty(pt1, "y").getClass().getName());
}
private static Object getProperty(ReflectPoint pt1) {
Object retVal = null;
PropertyDescriptor pd = null;
try {
pd = new PropertyDescriptor("y",pt1.getClass());
retVal = pd.getReadMethod().invoke(pt1);
} catch (Exception e) {
e.printStackTrace();
}
return retVal;
}
private static void setProperty(Object pt1, String propertyName,
Object value) {
/*PropertyDescriptor pd2;
try {
pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
pd2.getWriteMethod().invoke(pt1,value);
} catch (Exception e) {
e.printStackTrace();
}*/
try {
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd :pds){
if(pd.getName().equals(propertyName)){
pd.getWriteMethod().invoke(pt1,value);
break;
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
-
Beanutils工具包
- 演示用eclipse如何加入jar包,先只是引入beanutils包,等程序运行出错后再引入logging包。
- 在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。
- 用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
public static void main(String[] args) {
// TODO Auto-generated method stub
/*System.out.println(
PropertyUtils.getProperty(Sex.NONE, "title"));*/
Object bean = Sex.NONE;
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(bean.getClass());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor property:properties)
{
if(property.getName().equals("title"))
{
Method method = property.getReadMethod();
method.setAccessible(true);
Object retVal;
try {
retVal = method.invoke(bean, null);
System.out.println(retVal);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
注意: get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串. get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。
-
代码演示
Demo1
package com.wenhaitao.Ekt3.Demo1;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class Demo1 {
public static void main(String[] args) {
User user = new User();
PropertyDescriptor pd_name = null;
try {
pd_name = new PropertyDescriptor("uname", User.class);
Method method_setName = pd_name.getWriteMethod();
method_setName.invoke(user, "肥肥也");
PropertyDescriptor pd_pass = new PropertyDescriptor("upass", User.class);
Method method_setpass = pd_pass.getWriteMethod();
method_setpass.invoke(user, "54920");
System.out.println(user);
Method method_getname = pd_name.getReadMethod();
System.out.println(method_getname.invoke(user));
Method method_getpass = pd_pass.getReadMethod();
System.out.println(method_getpass.invoke(user));
// 遍历所有的属性
BeanInfo info = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println("属性名:" + pd.getName());
System.out.println("属性类型:" + pd.getPropertyType());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
User
package com.wenhaitao.Ekt3.Demo1;
public class User {
private String uname;
private String upass;
public User() {
}
public User(String uname, String upass) {
this.uname = uname;
this.upass = upass;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpass() {
return upass;
}
public void setUpass(String upass) {
this.upass = upass;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", upass='" + upass + '\'' +
'}';
}
}
运行结果:
[图片上传失败...(image-1868e8-1619860962534)]
Demo2
package com.wenhaitao.Ekt3.Demo2;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo2 {
public static void main(String[] args) {
User user = new User();
try {
BeanUtils.setProperty(user, "uname", "肥肥也");
BeanUtils.setProperty(user, "upass", "54920");
System.out.println(BeanUtils.getProperty(user, "uname"));
System.out.println(BeanUtils.getProperty(user, "upass"));
//给定一个保存了对象属性的map集合,
Map map = new HashMap();
map.put("uname", "papercy");
map.put("upass", "88888");
BeanUtils.populate(user, map);
System.out.println(user);
user = new User("paper", "66666");
Map mp = BeanUtils.describe(user);
Set set = mp.entrySet();
Iterator it = set.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
[图片上传失败...(image-39c5bc-1619860962534)]
-
Java Bean 特性
JavaBean 与其它 Java 类相比而言独一无二的特征:
- 提供一个默认的无参构造函数。
- 需要被序列化并且实现了 Serializable 接口。
- 可能有一系列可读写属性。
- 可能有一系列的 getter 或 setter 方法。
调用属性步骤:
- 根据属性名字获得属性对象(Field)
- 赋值:set(obj,value)
- 取值:get(obj)
- 如果需要强制访问类的私有成员,则需要设定:setAccessible(true);
-
ps: