------- android培训、java培训、期待与您交流! ----------
内省(IntroSpector)------JavaBean
内省就是对JavaBean进行操作的类的名字(IntroSpector)
JavaBean是符合特殊规则的的Java类, JavaBean中需要提供set/get方法, JavaBean能当做普通的类操作, 但是普通的类不一定能当做JavaBean操作
get和set后面定义的名字被称为JavaBean的属性,而不是类中定义的成员变量,JavaBean中的属性是判断set/get后面的字母,如果第二个字母是小写, 那么第一个字母也要变成小写,如果第二字母是大写, 那么第一个字母不用改变,例如下面的代码
package com.itcast.bean;
public class Person {
//定义一个属性x
int x;
//JavaBean必须符合下面的规则, 提供set/get方法
public int getAge() {
return x;
}
//这个类中有一个属性, 是age, 而不是x, get后面第二个字母是小写, 所以属性名是age
public void setAge(int x) {
this.x = x;
}
}
对JavaBean的两种内省操作
package cn.itcast.introspector;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import cn.itcast.bean.Person;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
//创建JavaBean对象
Person p = new Person();
//通过内省方法操作setAge方法
setProperty(p, "age", 5);
//通过内省方法操作getAge方法
System.out.println(getProperty(p, "age"));
}
//简单的内省操作JavaBean, 设置age属性的值
public static void setProperty(Object obj, String propertyName, int value) throws Exception {
//将属性名作为参数传入PropertyDescriptor对象
PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
//获得设置属性的方法
Method setMethod = pd.getWriteMethod();
setMethod.invoke(obj, value);
}
//复杂的内省操作JavaBean, 获得age属性的值
public static Object getProperty(Object obj, String propertyName) throws Exception {
//获得BeanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
//利用BeanInfo对象获得全部的全部的属性对象
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//定义一个变量用于存储结果
Object retValue = 0;
//遍历属性数组得到要获得的属性
for (PropertyDescriptor pd : pds) {
//判断当前属性的名字是否是传进来参数的名字
if (propertyName.equals(pd.getName())) {
//获得读取的方法
Method getMethod = pd.getReadMethod();
retValue = getMethod.invoke(obj);
break;
}
}
return retValue;
}
}
BeanUtils工具类
BeanUtils是Apache提供的一个操作JavaBean的工具类,提供了setProperty()和getProperty()可以直接对JavaBean的属性进行set/get
使用BeanUtils必须先在Apache官网下载BeanUtils工具包,将jar文件导入到工程,如果BeanUtils中的类还用到了其它的包下的类,那么同样将这个包导入到工程
BeanUtils还可以提供了方法将一个javaBean中的属性复制到另一个JavaBean中,这个方法声明是publicstatic copyProperties(java.lang.Object dest, java.lang.Object orig), BeanUtils可以将Javabean和Map相互转换,使用describe(object)方法可以将JavaBean中的属性转换为Map,使用populate(map)可以将Map中的元素转换为JavaBean的属性,BeanUtils可以对Map进行操作,操作的方法与操作JavaBean的一样
BeanUtils在堆JavaBean进行操作时,必须是以字符串的形式出入要操作属性的参数, 返回属性的类型也是字符串,例如操作setAge(10)方法需要这样写, setProperty(new Person(), “age”, “10”);这里的10要以字符串形式传入
PropertyUtils跟BeanUtils类一样是操作JavaBean的,它们的区别是PropertyUtils不用以字符串的形式传入要操作属性的参数,用属性本来的类型就可以, 返回的也是属性原来的类型
代码示例
package cn.itcast.introspector;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import cn.itcast.bean.Person;
public class BeanUtilsTest {
public static void main(String[] args) throws Exception {
// 创建一个Person对象
Person p = new Person();
// 用BeanUtils设置age属性
BeanUtils.setProperty(p, "age", "50");
// 用BeanUtils获得age属性, 并打印
System.out.println(BeanUtils.getProperty(p, "age"));
// 将Person的属性转换为Map
Map map = BeanUtils.describe(p);
System.out.println(map);
}
}
注解
注解是一种标记, 开发工具会通过反射来识别这种标记, 并根据标记做一些相应的事,注解可以加在包, 类,字段, 方法,方法的参数及局部变量上, 使用注解是其实就是创建了一个注解对象
注解的声明格式
public @interface MyAnnotation {}
声明注解的时候可以给注解定义保留在什么时期,一共有下面三种
@Retention(RetentionPolicy.SOUCE),仅对源代码注解有效
@Retention(RetentionPolicy.CLASS),在生成的class文件有效,不定义保留期默认是这个
@Retention(RetentionPolicy.RUNTIME),保留到运行期注解都有效
注解内可以定义属性, 属性的类型可以是8种基本类型, String类型, Class类型, Enum类型, Annocation类型或者前面提到类型的数组
在使用注解的时候传入参数格式是@MyAnnotation(属性=”值”),如果注解内只有一个属性, 并且属性名是value,那么括号里直接写属性的值就可以了, 就不用写”属性=”了
代码示例
package cn.itcast.annotation;
@MyAnnotation(10)
public class AnnotationTest {
public static void main(String[] args) {
// 判断类是否有传入的注解
if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {
// 通过反射得到注解中的元素
MyAnnotation ma = (MyAnnotation) AnnotationTest.class
.getAnnotation(MyAnnotation.class);
System.out.println(ma.color());
System.out.println(ma.value());
System.out.println(ma.arr().length);
}
}
}