您的位置:首页 > 职场人生

黑马程序员java学习<基础加强>—JavaBean

2013-06-23 02:19 609 查看
一、概述:

1、IntroSpector:即内省,是对内部进行检查,了解更多的底层细节。

2、内省的作用:主要针对JavaBean进行操作。

 

二、JavaBean

1、简述:

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

2)它是一种特殊的Java类,其中的方法名称等,都符合特殊的规则。只要一个类中含有get和set打头的方法,就可以将其当做JavaBean使用。

3)字段和属性:

字段就是我们定义的一些成员变量,如private String name;等

而属性是具有某些功能,Bean属性,是含有get或set方法的那些属性的字段,即这个变量的get属性,set属性等。

2、作用:

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

3、命名方式:

JavaBean的属性是根据其中的setter和getter方法来确定的,而不是依据其中的变量,如方法名为setId,则中文意思是设置Id,getId也是如此;去掉前缀,剩余部分就是属性名称,如果剩余部分的第二个字母小写,则把剩余部分改为小写。如:getAge/setAge-->age;gettime-->time;setTime-->time;getCPU-->CPU。

4、总之、一个类被当做JavaBean使用时,JavaBaan的属性是根据方法名推断出来的,它根本看不到Java类内部的成员变量。

5、JavaBean的好处:

一个符合JavaBean特点的类当做普通类一样可以使用,但是把它当做JavaBean类用肯定有好处的:

1)在JavaEE开发中,经常要使用JavaBean。很多环境就要求按JavaBean的方式进行操作,别人都这么用,那么就必须要求这么做。

2)JDK中提供了对JavaBean进行操作的API,这套API称为内省,若要自己通过getX的方式来访问私有x,可用内省这套API,操作JavaBean要比使用普通的方式更方便。

示例:

package cn.itcast.text1;

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 {

// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//"x"-->"X"-->"getX"-->MethodGetX-->
//内省的方式:
//属性描述符:PropertyDescriptor
//get属性信息
PropertyDescriptor pd =
new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
//set属性信息
Object value = 7;
PropertyDescriptor pd2 =
new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1,value);

System.out.println(pt1.getX());
}
*/
//上面的get或set代码分别通过选中要重构的代码,通过右击选重构获得get和set方法:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//一般方式:"x"-->"X"-->"getX"-->MethodGetX-->
//内省方式:
//通过get和set方法获取属性值
Object retVal = getProperty(pt1, propertyName);
System.out.println(retVal);

Object value = 7;
setProperty(pt1, propertyName, value);
System.out.println(pt1.getX());
}

//设置属性值的方法             //此处的类型为Object,通用,下同
private static void setProperty(Object rf, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
//创建属性描述符对象,将属性名称和加载文件等信息写入其中
PropertyDescriptor pd =
new PropertyDescriptor(propertyName,rf.getClass());
//通过反射的方法类Method,获取属性所对应的set方法
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(rf, value);
}
//获取属性值的方法
private static Object getProperty(Object rf, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
//创建属性描述符对象,获取属性所对应的名称和加载文件等信息
PropertyDescriptor pd =
new PropertyDescriptor(propertyName,rf.getClass());
//通过反射的方法类Method,获取属性所对应的get方法
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(rf);
return retVal;
}
}


 

三、对JavaBean的复杂内省操作:

1、在IntroSpector类中有getBeanInfo(Class cls)的方法。

2、获取Class对象的Bean信息,返回的是BeanInfo类型。

3、BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的BeanInfo的属性信息,返回一个PropertyDescriptor[]。

4、在通过遍历的形式,找出与自己想要的那个属性信息。

 

四、BeanUtils工具包:

1、BeanUtils等工具包都是由阿帕奇提供的,为了便于开发。

2、BeanUtils可以将8种基本数据类型进行自动的转换,因此对于非基本数据类型,就需要注册转换器Converter,这就需要ConverUtils包,

2、好处:

1)提供的set或get方法中,传入的是字符串,返回的还是字符串,因为在浏览器中,用户输入到文本框的都是以字符串的形式发送至服务器上的,所以操作的都是字符串。也就是说这个工具包的内部有自动将整数转换为字符串的操作。

2)支持属性的级联操作,即支持属性链。如可以设置:人的脑袋上的眼镜的眼珠的颜色。这种级联属性的属性连如果自己用反射,那就很困难了,通过这个工具包就可以轻松调用。

3、可以和Map集合进行相互转换:可将属性信息通过键值对的形式作为Map集合存储(通过staticjava.util.Map describe(java.lang.Object bean)的方法),也可以将Map集合转换为JavaBean中的属性信息(通过static voidpopulate(java.lang.Object bean, java.util.Map properties)的方法)。

4、示例:

1)设置和获取属性值:

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConvert
4000
er;
import org.junit.Test;

public class BeanUtilDemo {

/**
* BeanUtils使用
*/

@Test
public void test1() throws Exception{
//创建对象,设置属性值
Person p = new Person();
BeanUtils.setProperty(p, "name", "zzz");
String name = BeanUtils.getProperty(p, "name");
System.out.println(name);
}

@Test
public void test2() throws Exception{
//创建对象,传入属性值
Person p = new Person();
String name = "wangwu";
String age = "23";
String hight = "173.5";
//设置属性值
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "hight", hight);
//获取属性值
System.out.println(BeanUtils.getProperty(p, "name"));
System.out.println(BeanUtils.getProperty(p, "age"));
System.out.println(BeanUtils.getProperty(p, "hight"));
}

 

2)未注册的属性值的获取和设置

//获取未注册的属性,即非八种基本数据类型的引用类型
//private Date birthday
@Test
public void test3() throws Exception{
Person p = new Person();
String name = "wangwu";
String age = "23";
String hight = "173.5";
String birthday = "1990-09-09";
ConvertUtils.register(new Converter() {
//注册器Converter接口中方法的重写
@Override
public Object convert(Class type, Object value) {
if(value == null)
return null;
if(!(value instanceof String))
throw new ConversionException("只支持String类型的转换");
String str = (String) value;
if(value.equals(""))
return null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
return sdf.parse(str);
}catch(ParseException e){
throw new RuntimeException(e);//异常链不能掉,这里必须写上e
}
}},
Date.class);

//测试
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "hight", hight);
BeanUtils.setProperty(p, "birthday", birthday);
System.out.println(BeanUtils.getProperty(p, "name"));
System.out.println(BeanUtils.getProperty(p, "age"));
System.out.println(BeanUtils.getProperty(p, "hight"));
System.out.println(BeanUtils.getProperty(p, "birthday"));
}

//使用已经写好的注册器DateLocaleConverter
@Test
public void test4() throws Exception{
Person p = new Person();
String name = "wangwu";
String age = "23";
String hight = "173.5";
String birthday = "1990-09-09";
//将日期注册到BeanUtils上
ConvertUtils.register(new DateLocaleConverter(), Date.class);//提供的注册器不健壮,因为传入空字符串,就会报错
//所以,当没有提供注册器或需要加强注册器的时候,可以自己写
//测试
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "hight", hight);
BeanUtils.setProperty(p, "birthday", birthday);
System.out.println(BeanUtils.getProperty(p, "name"));
System.out.println(BeanUtils.getProperty(p, "age"));
System.out.println(BeanUtils.getProperty(p, "hight"));
System.out.println(BeanUtils.getProperty(p, "birthday"));
Date date = p.getBirthday();
System.out.println(date.toLocaleString());
}


3)Map集合在BeanUtils中的应用:

//Map集合在BeanUtils中的应用
@Test
public void test5() throws Exception {
/*
* JDK 7.0新特性:
* Map map = {"name" : "zs", "age" : 22, "hight" : 176.5};
*/
//将数据存入集合
Map map = new TreeMap();
map.put("name", "zhangsan");
map.put("age", "20");
map.put("hight", "172.5");
map.put("birthday", "1999-10-02");

//注册器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
//获取属性
Person p = new Person();
BeanUtils.populate(p, map);

System.out.println(BeanUtils.getProperty(p, "name"));
System.out.println(BeanUtils.getProperty(p, "age"));
System.out.println(BeanUtils.getProperty(p, "hight"));
System.out.println(BeanUtils.getProperty(p, "birthday"));

}

//属性链
@Test
public void test6() throws Exception {
Person p = new Person();
BeanUtils.setProperty(p, "birthday.time", "111212");
System.out.println(BeanUtils.getProperty(p, "birthday.time"));
}


 

5、补充:

1)BeanUtils是以字符串的形式进行操作的

2)PropertyUtils是以传入值本身的类型进行操作的。

//PropertyUtils可直接解析为指定类型,而BeanUtils只能指定字符串的类型
@Test
public void test7() throws Exception {
Person p = new Person();
System.out.println("-----BeanUtiles-------");
BeanUtils.setProperty(p, "age", "22");//字符串形式
System.out.println(BeanUtils.getProperty(p, "age"));
System.out.println(BeanUtils.getProperty(p, "age").getClass().getName());

System.out.println("-----PropertyUtiles-------");
PropertyUtils.setProperty(p, "age", 22);//Integer形式
System.out.println(PropertyUtils.getProperty(p, "age"));
System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息