内省与JavaBean
概述
JavaBean代表一类特殊的Java类,这种类主要用来存储和传递属性信息,JavaBean中的方法主要用于设置和获取这些私有属性,他们有一定的命名规则,我们可以把它们想象为一个侧重属性信息的类,如JSP中的表单信息打包一样,这些信息就可以封装在一个JavaBean对象中,通过一些特殊的方式来操作。
Introspector,即为内省
public class Introspector- extends Object
Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
简单说,Introspector就是一种操作JavaBean的标准方式
JavaBean一些简单操作
写一个Bean类用作测试
1: public class Bean {
2: private String name;
3: private int age;
4: private int num;
5: private int score;
6:
7: public Bean(String name, int age, int num, int score) {
8: super();
9: this.name = name;
10: this.age = age;
11: this.num = num;
12: this.score = score;
13: }
14: public String getName() {
15: return name;
16: }
17: public void setName(String name) {
18: this.name = name;
19: }
20: public int getAge() {
21: return age;
22: }
23: public void setAge(int age) {
24: this.age = age;
25: }
26: public int getNum() {
27: return num;
28: }
29: public void setNum(int num) {
30: this.num = num;
31: }
32: public int getScore() {
33: return score;
34: }
35: public void setScore(int score) {
36: this.score = score;
37: }
38: }
实现set和get方法的简单操作
1: public class BeanTest {
2:
3: /**
4: * @param args
5: */
6: public static void main(String[] args) {
7:
8: //获取对象
9: Bean b = new Bean("Shawn",12,1,97);
10: //获取类字节码文件
11: Class beanClass = Bean.class;
12: //设置需要操作的属性名
13: String propertyName = "name";
14:
15: //调用set和get方法
16: System.out.println(getProperty(beanClass, b, propertyName, null));
17: setProperty(beanClass, b, propertyName, new Object[]{"Feng"});
18: System.out.println(getProperty(beanClass, b, propertyName, null));
19:
20: }
21: //封装javabean的set方法
22: private static void setProperty(Class beanClass,Object obj,String propertyName,Object[] values){
23: try {
24: //获取属性描述符对象
25: PropertyDescriptor pd = new PropertyDescriptor(propertyName, beanClass);
26: //得到set方法对象
27: Method setMethod = pd.getWriteMethod();
28: //利用反射执行set方法
29: setMethod.invoke(obj, values);
30: } catch (IllegalArgumentException e) {
31: // TODO Auto-generated catch block
32: e.printStackTrace();
33: } catch (IntrospectionException e) {
34: // TODO Auto-generated catch block
35: e.printStackTrace();
36: } catch (IllegalAccessException e) {
37: // TODO Auto-generated catch block
38: e.printStackTrace();
39: } catch (InvocationTargetException e) {
40: // TODO Auto-generated catch block
41: e.printStackTrace();
42: }
43: }
44: //封装javabean的get方法
45: private static Object getProperty(Class beanClass,Object obj,String propertyName,Object[] args){
46: Object retVal = null;
47: try {
48: //获取属性描述符对象
49: PropertyDescriptor pd = new PropertyDescriptor(propertyName, beanClass);
50: //得到get方法对象
51: Method getMethod = pd.getReadMethod();
52: //利用反射执行get方法
53: retVal = getMethod.invoke(obj, args);
54: } catch (IllegalArgumentException e) {
55: // TODO Auto-generated catch block
56: e.printStackTrace();
57: } catch (IntrospectionException e) {
58: // TODO Auto-generated catch block
59: e.printStackTrace();
60: } catch (IllegalAccessException e) {
61: // TODO Auto-generated catch block
62: e.printStackTrace();
63: } catch (InvocationTargetException e) {
64: // TODO Auto-generated catch block
65: e.printStackTrace();
66: }
67: return retVal;
68: }
69: }
利用内省实现一些复杂操作
1: public class BeanTest2 {
2:
3: /**
4: * @param args
5: * @throws IntrospectionException
6: * @throws InvocationTargetException
7: * @throws IllegalAccessException
8: * @throws IllegalArgumentException
9: */
10: public static void main(String[] args) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
11:
12: //获取对象
13: Bean b = new Bean("Shawn",12,1,97);
14: //获取类字节码文件
15: Class beanClass = Bean.class;
16: //设置需要操作的属性名
17: String propertyName = "name";
18:
19: //根据类字节码对象获取Bean信息
20: BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
21: //利用内省获取所有的属性描述符
22: PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
23: //遍历所有的属性描述符,找到要操作的属性,进行操作
24: for(PropertyDescriptor pd : pds){
25: if(pd.getName().equals(propertyName)){
26: Method setMethod = pd.getWriteMethod();
27: Method getMethod = pd.getReadMethod();
28: System.out.println(getMethod.invoke(b, null));
29: setMethod.invoke(b, "Feng");
30: System.out.println(getMethod.invoke(b, null));
31: }
32: }
33: }
34: }
BeanUtils工具包
BeanUtils工具包是apach提供的一套非常方便的用于操作JavaBean的工具
BeanUtil实现set和get方法
1: public class BeanUtilTest {
2:
3: /**
4: * @param args
5: * @throws NoSuchMethodException
6: * @throws InvocationTargetException
7: * @throws IllegalAccessException
8: */
9: public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
10:
11: //获取对象
12: Bean b = new Bean("Shawn",12,1,97);
13: //设置需要操作的属性名
14: String propertyName = "score";
15:
16: //利用BeanUtils获取属性值
17: System.out.println(BeanUtils.getProperty(b, propertyName));
18: //利用BeanUtils设置属性值
19: BeanUtils.setProperty(b, propertyName, "33");
20: System.out.println(BeanUtils.getProperty(b, propertyName));
21: }
22: }
我们可以看到,即便操作的是int型的属性,接收的仍然是字符串数据
BeanUtils包中还提供一个类PropertyUtils,也具有setProperty与getProperty的方法,与BeanUtils不同的是,传入的参数不需要进行类型转换,也就是说,如果BeanUtils中的方法类型转换出了问题时,可以采用PropertyUtils中的方法,直接传入对应类型的参数,同样可以达到目的。
同时,BeanUtils还支持属性的级联操作
比如一个人内部有心脏,而心脏内部又有左心房和右心房,那么我们可以直接通过BeanUtils设置和获取心脏的内部属性
1: public class Heart{
2: private String left;
3: private String right;
4: public String getLeft() {
5: return left;
6: }
7: public void setLeft(String left) {
8: this.left = left;
9: }
10: public String getRight() {
11: return right;
12: }
13: public void setRight(String right) {
14: this.right = right;
15: }
16: }
1: public class Person{
2: private Heart heart = new Heart();
3: private Date birthday;
4: public Date getBirthday() {
5: return birthday;
6: }
7: public void setBirthday(Date birthday) {
8: this.birthday = birthday;
9: }
10: public Heart getHeart() {
11: return heart;
12: }
13: public void setHeart(Heart heart) {
14: this.heart = heart;
15: }
16: }
1: public class BeanUtilsTest2 {
2:
3: /**
4: * @param args
5: * @throws NoSuchMethodException
6: * @throws InvocationTargetException
7: * @throws IllegalAccessException
8: */
9: public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
10: // TODO Auto-generated method stub
11: Person p = new Person();
12: System.out.println(BeanUtils.getProperty(p, "heart.left"));
13: BeanUtils.setProperty(p, "heart.left", "lll");
14: System.out.println(BeanUtils.getProperty(p, "heart.left"));
15: }
16: }
还有一个重要的操作,BeanUtils可以将Map集合对象与JavaBean对象的对应属性内容进行转换
1: public class BeanUtilsTest3 {
2:
3: /**
4: * @param args
5: * @throws InvocationTargetException
6: * @throws IllegalAccessException
7: * @throws NoSuchMethodException
8: */
9: public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
10:
11: //将JavaBean的属性信息映射到一个Map集合中
12: Map map = new HashMap();
13: Bean b = new Bean("Shawn", 12, 14, 90);
14: map = BeanUtils.describe(b);
15: System.out.println(map);
16:
17: //将map集合中的属性写入到JavaBean对象中
18: map = new HashMap();
19: map.put("name", "Feng");
20: map.put("score", 22);
21: BeanUtils.populate(b, map);
22: System.out.println(b.toString());
23: }
24: }
以上三点便是BeanUtils最常用的一些操作和特点,可以看到,BeanUtils的操作非常方便快捷,现在已经很普及了
JavaBean的命名规则
由于JavaBean中只有set和get方法是对外可见的,所以JavaBean内部属性用什么名字并不重要,只要设置好方法名称即可
一般规则是
如果方法名称为setXxx和getXxx,那么表示propertyName全为小写xxx
如果方法名称为setXXx或者setXXX,那么表示propertyName为对应的XXx以及XXX
一般setXxx以及setXXX比较常见,一个代表普通的变量,一个代表具有特殊含义的变量
所以我们写方法名称时尽量按照这个命名规则写,设置propertyName时使用相对应的名称即可
内省与JavaBean的更多相关文章
- 内省(introspector)------>JavaBean
内省(introspector)------>JavaBean 1.问什么要学内省? 开发框架时,经常需要Java对象的属性来来封装程序的数据,每次使用反射技术完成此操作过于 ...
- 内省、JavaBean、PropertyDescriptor类、Introspector类、BeanUtils工具包、注解、Rentention、Target、注解的基本属性和高级属性
本文转载自:http://blog.sina.com.cn/s/blog_5d65a16901011kom.html 关键字:内省.JavaBean.PropertyDescriptor类.Int ...
- 内省操作javabean的属性
import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector ...
- 由内省引出JavaBean的讲解
IntroSpector--内部检查,了解更多细节--内省---JavaBean 一.JavaBean JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用户访问 ...
- java 内省 了解JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则. 如果要在两个模块之间传递多个信息,可以将这些信息封装到一个Jav ...
- 由内省引出JavaBean的应用
IntroSpector-->javaBean-->特殊的java类 get和set方法 ReflectPoint pt1 = new ReflectPoint(3,5); String ...
- 使用内省的方式操作JavaBean
import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; im ...
- java 深入技术八(内省)
1. javabean的软件设计思想 2.内省:封装了java反射,提供直接操作属性的Setter和getter方法的方法 3.核心API:BeanInfo java 的描述信息,Introspect ...
- 黑马程序员——【Java高新技术】——JavaBean、注解
---------- android培训.java培训.期待与您交流! ---------- 一.JavaBean * 通过内省引入JavaBean:内省对应的英文全程是IntroSpector.在J ...
随机推荐
- springMVC从上传的Excel文件中读取数据
示例:导入客户文件(Excle文件) 一.编辑customer.xlsx 二.在spring的xml文件设置上传文件大小 <!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1 ...
- PAT-乙级-1024. 科学计数法 (20)
1024. 科学计数法 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 HOU, Qiming 科学计数法是科学家用来表示很 ...
- 如何保护 .NET 应用的安全?
自从 Web 应用能给访问者提供丰富的内容之后,黑客们就把目光转向任何他们能够破坏,损毁,欺骗的漏洞.通过网络浏览器提供的应用越来越多,网络罪犯们可以利用的漏洞数量也呈指数增长起来. 大多数企业都依赖 ...
- POJ2031Building a Space Station
http://poj.org/problem?id=2031 题意:你是空间站的一员,太空里有很多球形且体积不一的“小房间”,房间可能相距不近,也可能是接触或者甚至是重叠关系,所有的房间都必须相连,这 ...
- java I/O Stream 代码学习总结
一. InputStream 类学习介绍 mark方法 public void mark(int readlimit) 在此输入流中标记当前的位置.对 reset 方法的后续调用会在最后标记的位置重新 ...
- java使用redis
1.redis和memecache这种缓存框架,都分为服务器端和客户端. 我们在项目中使用,相当于客户端,要引入客户端使用redis的jar包 首先你需要下载驱动包,下载 jedis.jar,确保下载 ...
- 优化tomcat——jvm
Tomcat 的启动参数位于tomcat的安装目录\bin目录下,如果你是Linux操作系统就是catalina.sh文件,如果你是Windows操作系统那么你需要改动的就是catalina.bat文 ...
- J2EE中你必须了解的13种技术规范
1)JDBC(Java Database Connectivity): JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDCB对数据 ...
- Codeforces 380A - Sereja and Prefixes
原题地址:http://codeforces.com/problemset/problem/380/A 让期末考试整的好久没有写题, 放假之后由于生病也没怎么做,新年的第一场CF也不是那么在状态,只过 ...
- MySQL优化器 limit影响的case
测试的用例中,因为limit的大小不同,而产生了完全不同的执行计划: 1. 测试case: create table t1 ( f1 ) not null, f2 ) not null, f3 ) n ...