JavaBean属性操作复习

以下笔记是根据张孝祥的视频整理而成!

内省API、JavaBean、BeanUtils工具的使用

一、内省API

1、什么是JavaBen

        Javabean是一种特殊的java类,主要用来传递数据信息的,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

        如下程序所示就表示一个JavaBean;

package com.wisdragon.introspector;
import java.util.Date;
/**
 * 描述: 建立一个JavaBean
 */
public class Student {

	private String name;
	private int age;
//	private Date birthday;
	private Date birthday = new Date();
	
	public Student() {
		super();
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		
		return this.name + ":" + this.age;
	}
}

        从以上的类中可以看出,在程序中使用setter和getter方法来访问类的私有属性。那么怎么判断类中的属性呢?以上程序中name和age属性都已用private进行封装,对于外界是透明的。因此,不能认为name和age就是此类的属性,判断类的属性需要从getter和setter方法入手。观察下面的setAge()方法

public void setAge(int age) {
       this.age = age;
}

        setAge()看做设置age值,因此age才是此类的属性。

        如以下的程序所示: 类中的属性是count,而不是num。

public class Ball {
	private int num;
	
	public void setCount(int count){
		
		this.num = count;
	}
}

2、什么是内省

        内省是JDK提供的一套用户操作JavaBean的API。这些API位于java.beans包中。

        如果给你一个属性名(假设为name),需要你通过这个属性名获取这个属性的值,该怎么做?

       普通流程:   name -->  getName()

       此处属性变get或set有一定的要求,如果属性名的第二个字母为小写,则将第一个字母变为大写(name-->Name),如果第二个字母为大写,则不需要变化。(CPU-->CPU)   。

       使用内省API: 获取该属性的getter或setter方法,使用反射的invoke()执行方法。

      要使用内省,则需要学习以下的API:

public class PropertyDescriptor   extends FeatureDescriptor

                                                 -----描述 Java Bean 通过一对存储器方法导出的一个属性

构造方法:publicPropertyDescriptor(String propertyName,Class<?> beanClass)

                                throwsIntrospectionException
主要的方法:
1、public Method getReadMethod()   ------- 获得应该用于读取属性值的方法。
2、public Method getWriteMethod()   -------  获得应该用于写入属性值的方法。

范例:使用内省API完成对Student类中属性的操作

package com.wisdragon.introspector;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class IntroSpectorDemo1 {

	public static void main(String[] args)throws Exception{
		
		Student student = new Student("黄玉泽", 22);
		//简单的方式
		String propertyName = "name";	//属性名
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, Student.class);
		/*
		 * PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。 
		 */
		//取值
		Method method1 = pd.getReadMethod();
		Object retVal = method1.invoke(student, null);
		System.out.println(retVal);
		
		//设置值
		String property = "age";
		PropertyDescriptor p = new PropertyDescriptor(property, Student.class);
		Method m = p.getWriteMethod();
		m.invoke(student, 23);
		System.out.println(student.toString());
}


结果:


黄玉泽

黄玉泽 :23

        对于以上的程序还可以使用第二种方式实现:

范例: 使用Instrospector 实现同样的功能

package com.wisdragon.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class IntroSpectorDemo1 {

	public static void main(String[] args)throws Exception{
		
		Student student = new Student("黄玉泽", 22);

		//采用更为复杂的方式,完成以上同样的功能,使用Instrospector类完成
		BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal1 = null;
		for(PropertyDescriptor p1 : pds){
			
			if(p1.getName().equals(property)){
				
				Method method = p1.getReadMethod();
				retVal1 = method.invoke(student, null);
				break;
			}
		}
		System.out.println(retVal1);
	}
	
}


结果: 22

        使用JDK可以完成对JavaBean属性的操作。Apache组织提高了开源项目BeanUtils来方便地操作JavaBean。

二、BeanUtils的使用

2.1 属性的取得和设置

方法说明

public static String getProperty(Object bean,String name)   throws IllegalAccessException,

            InvocationTargetException,

                   NoSuchMethodException
返回JavaBean的属性值
publicstatic void setProperty(Objectbean, String name, Object value) throws IllegalAccessException,                            InvocationTargetException为JavaBen某个属性设置值

        使用BeanUtils工具类可以很方便地获取JavaBean的属性值和设置属性值。首先来学习以上两个方法:

       从以上的方法一中可以看出,使用BeanUtils获取特定属性的的值返回值都是String,这一点在在开发中是非常便利的,比如我们需要获取一个类型为Date的属性的值,通常需要进行类型转换成String,在进行其他操作,但是BeanUtils就可以帮你完成。从方法二中可以看出,第三个参数为Object object,也就是说我们为某个特定属性赋值可以用Object类型传入,BeanUtils为你处理类型转换。

范例:使用BeanUtils操作JavaBean

package com.wisdragon.introspector;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;

/**
 * 描述: 使用BeanUtils操作JavaBean
 * 更新记录:
 */
public class BeanUtilsDemo1 {

	public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		Student stu = new Student("lee", 22);
		//获取属性值
		String retVal = BeanUtils.getProperty(stu, "age");
		System.out.println(retVal);
		//设置属性值
		BeanUtils.setProperty(stu, "age", "20");  //BeanUtils做了类型转化,很方便
		//BeanUtils.setProperty(stu, "age", 20);
		System.out.println(stu.getAge());
		
	}
}

       从上面的例子中,我们可以看到,很方便的取得了JavaBean的属性和设置属性,同时返回的值为String,设置值时,age属性的类型为int,可以用字符串传入。

2.2 属性链操作

       在开发中对象中包括属性,而此属性同时也是一个对象是常见的事,而这样的属性设置在BeanUtils中很好的实现了这一操作。比如:java.util.Date中有一个setTime()方法,在本文前面的JavaBean例子中已有Date类型的对象了,下面就以这个方法为例。

范例:操作属性链

package com.wisdragon.introspector;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * 描述: 使用BeanUtils操作JavaBean
 * 更新记录:
 */
public class BeanUtilsDemo1 {

	public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		Student stu = new Student("lee", 22);
		//支持属性链操作
		//java.util.Date 中有一个setTime()方法
		BeanUtils.setProperty(stu, "birthday.time", "19920721");
		System.out.println(BeanUtils.getProperty(stu, "birthday.time"));   //如果不为birthday初始化为一个值,则取得null
	
	}
}

结果: 19920721

        从上面的例子中可以看出使用属性.属性代替方法中的属性参数即可。

2.3 其他API   

        在BeanUtils中还有写API也是常用的,比如在开发中,我们需要将JavaBean转换成一个Map结构,同样也可以反过来操作,BeanUtils提供了API来实现这样的需求。见以下的方法:

方法说明
public static Map<String,String> describe(Object bean) throws IllegalAccessException,InvocationTargetException, NoSuchMethodException将JavaBean中的属性-值封装成Map结构
public static void populate(Object bean, Map<String,? extendsObject> properties)  throws IllegalAccessException,                        InvocationTargetException将Map结构中的键值对填充到JavaBean中

范例:JavaBean与Map之间的转换

package com.wisdragon.introspector;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;

public class BeanUtilsDemo1 {

	public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		Student stu = new Student("lee", 22);
		/*
		 * describe(Object bean)   返回值:Map<String,String>
		 * 将JavaBean转换为Map
		 */
		Map<String, String> map = BeanUtils.describe(stu);
		System.out.println(map.get("name"));
		System.out.println(map.get("age"));
		System.out.println("----------------------------------------------");
		/*
		 *  populate(Object bean, Map<String,? extends Object> properties)
		 *  Populate(构建) the JavaBeans properties of the specified bean, based on the specified name/value pairs.
		 */
		Map<String, String> beanMap = new HashMap<String, String>();
		beanMap.put("name", "huangyuze");
		BeanUtils.populate(stu, beanMap);
		System.out.println(stu);
		System.out.println("----------------------------------------------");
	}
}

        在使用Map结构填充JavaBean时,其Map结构需要符合一定的要求,其键的名称需要与JavaBean的属性名称对应。

2.4 PropertyUtils的使用

       我们还可以使用PropertyUtils来完成JavaBean属性的设置与获取,首先来学习这个类的结构:

  • java.lang.Object
                          org.apache.commons.beanutils.PropertyUtil

       此类也在beanutils包中,只是该类有以下特点:

       -| 获取属性值的类型为该属性原始的类型

       -| 设置属性值时的值类型只能是该属性原始的类型

范例:使用PropertyUtils类完成JavaBean属性的操作

package com.wisdragon.introspector;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * 描述: 使用BeanUtils操作JavaBean
 * 更新记录:
 */
public class BeanUtilsDemo1 {

	public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		Student stu = new Student("lee", 22);
		/*
		 *  PropertyUtils类的使用
		 *  get属性返回的结果为该属性本来的类型,set属性时只接收该属性本来的类型
		 */
		Object o = PropertyUtils.getProperty(stu, "age");
		System.out.println(o instanceof Integer);  //true
//		PropertyUtils.setProperty(stu, "age", "22");  //参数类型不匹配
		PropertyUtils.setProperty(stu, "age", 18);  //参数类型不匹配
		System.out.println(stu);
	}
}

三、 总结

        1、JavaBean是一种特殊的类,其属性的设置和获取方法都符合一定的规则。

        2、可以使用JDK提供的内省API   来操作JavaBean的属性。

        3、可以使用BeanUtils工具包提供的类来方便的操作JavaBean。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值