黑马程序员-JavaBean类与java内省总结

本文深入解析JavaBean的特点与使用方法,包括JavaBean类的属性定义、getter/setter方法的规则,以及如何利用内省和Beanutils工具包更便捷地操作JavaBean。同时提供实例代码演示关键概念的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------


一、JavaBean类概述

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

2、如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要相应的方法来访问,如getter方法和setter方法。

3、JavaBean的属性是根据其中的getter方法和setter方法来确定的,而不是根据其中的成员变量。举个例子,如果某个JavaBean类有方法setId()与getId(),那么我们认为它有个叫做id的属性,至于它内部实际封装的私有成员变量叫什么则不必关心。

4、根据方法名推断属性名的规则:

1)去掉set/get前缀,剩余部分就是属性名。2)若剩余部分的第二个字母为小写,则将剩余部分的首字母改为小写;若其为大写,则剩余部分的首字母仍为大写。举例,

setId()的属性名:id;

isLast()的属性名:last;

setCPU的属性名:CPU;

5、一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当作JavaBean类使用会带来一些额外好处:

1)java EE开发中,经常会使用到JavaBean类。很多环境要求按JavaBean方式进行操作,别人都这么用和要求这么做,我们也别无选择。

2)JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。使用内省操作JavaBean比使用普通类的方式更加方便。


二、内省

1、内省的概念

内省,英文名introspector,意思是自省、反省。它主要用于对JavaBean类进行操作。

2、通过内省对JavaBean进行操作

例1:简单的操作方式

package com.cn.itcast;

public class ReflectPoint {
	private int x;
	private int y;
	
	public ReflectPoint(int x,int y){
		super();
		this.x=x;
		this.y=y;
	}

	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}
package com.cn.itcast;

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

public class IntrospectorTest {

	public static void main(String[] args) throws Exception{
		ReflectPoint rp=new ReflectPoint(3, 5);  
		String propertyName="x";
		
		//通过普通反射方式获取属性x的值时,需要经历下面几个步骤,十分繁琐
		//"x"-->"X"-->"getX"-->methodGetX-->x
		
		//通过内省,获取x属性的值
		PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());//通过属性名,获取该对象rp下该属性x的属性描述器
		Method methodGetX=pd.getReadMethod();//通过属性描述器,获取该属性x的读方法,即getter方法
		Object retVal=methodGetX.invoke(rp);//利用反射调用该getter方法,获取属性x的值
		System.out.println(retVal);
		
		//通过内省,设置x属性的值
		Method methodSetX=pd.getWriteMethod();//通过属性描述器,获取该属性x的写方法,即setter方法
		methodSetX.invoke(rp, 7);////利用反射调用该setter方法,设置属性x的值
		System.out.println(rp.getX());
	}
}

输出结果:
3
7

利用重构,将例1中的代码进行简化:

public class IntrospectorTest {

	public static void main(String[] args) throws Exception{
		ReflectPoint rp=new ReflectPoint(3, 5);  
		String propertyName="x";
		
		Object retVal = getProperty(propertyName, rp);
		System.out.println(retVal);
		
		Object value=7;
		setProperty(propertyName, rp, value);
		System.out.println(rp.getX());
	}

	private static void setProperty(String propertyName, Object rp,
			Object value) throws IntrospectionException,
			IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());
		Method methodSetX=pd.getWriteMethod();
		methodSetX.invoke(rp, value);
	}

	private static Object getProperty(String propertyName, Object rp)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
		PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());
		Method methodGetX=pd.getReadMethod();
		Object retVal=methodGetX.invoke(rp);
		return retVal;
	}
}

例2:较麻烦的操作方式

public class IntrospectorTest {

	public static void main(String[] args) throws Exception{
		ReflectPoint rp=new ReflectPoint(3, 5);  
		String propertyName="x";
		
		//较麻烦的操作方式
		BeanInfo beanInfo=Introspector.getBeanInfo(rp.getClass());  //获取该JavaBean类的beanInfo,它存储了该JavaBean的所有属性信息
		PropertyDescriptor[] pds= beanInfo.getPropertyDescriptors();//获取该JavaBean类的所有属性描述器
		Object retVal=null;
		for(PropertyDescriptor pd:pds){
			if(pd.getName().equals(propertyName)){              //判断是否x属性的描述器 
				Method methodGetX=pd.getReadMethod();
				retVal=methodGetX.invoke(rp);
				break;
			}			
		}
		System.out.println(retVal);//3
	}
}

3、Beanutils工具包

Beanutils工具包是阿帕奇公司提供的开源工具包,用于更方便地操作JavaBean类

例3:

package com.cn.itcast;

public class ReflectPoint {
	private Date birthday=new Date();
	private int x;
	private int y;
	
	public ReflectPoint(int x,int y){
		super();
		this.x=x;
		this.y=y;
	}

	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}
package com.cn.itcast;

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

public class IntrospectorTest {

	public static void main(String[] args) throws Exception{
		ReflectPoint rp=new ReflectPoint(3, 5);  
		String propertyName="x";
		
		//利用Beanutils工具包操作JavaBean类
		System.out.println(BeanUtils.getProperty(rp, propertyName));//直接获取某个对象的某个属性的值,类似例1中重构后的方法
		BeanUtils.setProperty(rp, propertyName,"9");//直接设置某个对象的某个属性的值,类似例1中重构后的方法,但注意其接收的值类型为Object,常用String类型,更符合开发实际需求
		System.out.println(rp.getX());
		System.out.println(BeanUtils.getProperty(rp, propertyName).getClass().getName());//说明该方法返回值为String类型,比例1中重构后的方法更符合开发实际需求
		
		//支持对属性链的连续调用
		BeanUtils.setProperty(rp, "birthday.time", "111");
		System.out.println(BeanUtils.getProperty(rp, "birthday.time"));
		
		//get方法返回该属性本来的类型,set方法只接受该属性本类的类型
		PropertyUtils.setProperty(rp, propertyName, 12);
		System.out.println(rp.getX());
	}
}
输出结果:

3
9
java.lang.String
111
12



---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值