关于Java反射机制的一个实例

*
关于Java反射机制的一个实例
* http://developer.51cto.com 2009-06-19 13:59 abruzzi javaeye 我要评论(0)

本文向您展示Java反射机制的一个实例,该实例持简单EL的taglib,基本上实现了多级bean的属性的访问。

JSP的规范中,有个表达式语言(Expression Language, 简称EL),可以算是一个微型的语言,其中对request, page, session, application中预存的JavaBean对象的引用方式很是简单。最近正好需要写一个支持简单EL的taglib,所以就研究了下Java反射机制,目前基本上实现了多级bean的属性的访问,经测试,还是可以用的。如:

1. public static void main(String[] args){
2. UserBean bean = new UserBean();
3. bean.setName("John Abruzzi");
4. bean.setNick("Abruzzi");
5. bean.setAge(24);
6.
7. AddressBean addr = new AddressBean();
8. addr.setZip("0086");
9. addr.setStreet("Bell Street #12");
10. bean.setAddress(addr);
11.
12. System.out.println(BeanParser.doParse(bean, "bean.address.street"));
13. System.out.println(BeanParser.doParse(bean, "bean.address.zip"));
14. System.out.println(BeanParser.doParse(bean, "bean.name"));
15. System.out.println(BeanParser.doParse(bean, "bean.nick"));
16. System.out.println(BeanParser.doParse(bean, "bean.age"));
17. }

需要可以输出:

1. Bell Street #12
2. 0086
3. John Abruzzi
4. Abruzzi
5. 24

反射,即由一个抽象的对象(如Object),取出这个具体对象的属性或者方法(就EL中关于Bean的引用来说,这个定义已经够了)。在EL中,对一个Bean的某字段进行引用,只需 ${bean.field},当然,这个bean是已经被set到容器中的,这就是Java反射机制。

我们从容器中取出以bean为名字的Object,通过Java反射机制知道它的真实类型,然后通过field以javabean规范拼出方法名,进行调用,如果这个表达式是多级的,如${bean.field.field},其中第一个field本身就是一个bean对象,同样需要递归的进行解析。

大概原理就是这些了,看代码吧:

现有一个UserBean, 其中的一个字段Address本身又是一个AddressBean。

1. package elparser;
2.
3. public class AddressBean {
4. private String street;
5. private String zip;
6.
7. public String getZip() {
8. return zip;
9. }
10.
11. public void setZip(String zip) {
12. this.zip = zip;
13. }
14.
15. public String getStreet() {
16. return street;
17. }
18.
19. public void setStreet(String street) {
20. this.street = street;
21. }
22.
23. }

然后是UserBean

1. package elparser;
2.
3. public class UserBean {
4. private String name;
5. private String nick;
6. private AddressBean address;
7. private int age;
8.
9. public int getAge(){
10. return this.age;
11. }
12.
13. public void setAge(int age){
14. this.age = age;
15. }
16.
17. public String getName() {
18. return name;
19. }
20. public void setName(String name) {
21. this.name = name;
22. }
23. public String getNick() {
24. return nick;
25. }
26. public void setNick(String nick) {
27. this.nick = nick;
28. }
29. public AddressBean getAddress() {
30. return address;
31. }
32. public void setAddress(AddressBean address) {
33. this.address = address;
34. }
35. }

Bean都是很简单的,考虑到对基本类型的支持,所以在UserBean中加入一个int型的字段age

好了,看看怎么通过一个串和一个对象来取出其中的字段来:

1. package elparser;
2.
3. import java.lang.reflect.Method;
4.
5. public class BeanParser {
6.
7. private static String getMethodName(String property, String prefix){
8. String prop = Character.toUpperCase(property.charAt(0))+property.substring(1);
9.
10. String methodName = prefix + prop;
11.
12. return methodName;
13. }
14.
15. private static Object parse(Object bean, String expr){
16. Class beanClass = bean.getClass();
17.
18. Method method = null;
19. Object result = null;
20.
21. try{
22. //这两步是关键,get方法不需要传入参数,所以只是new出两个空数组传入
23. method = beanClass.getMethod(getMethodName(expr, "get"), new Class[]{});
24. result = method.invoke(bean, new Object[]{});
25. }catch(Exception e){
26. System.out.println(e.getMessage());
27. }
28.
29. return result;
30. }
31.
32. public static Object doParse(Object bean, String expr){
33. String keys[] = expr.split("\\.");
34.
35. Object obj = null;
36.
37. for(int i = 1; i < keys.length;i++){
38. obj = parse(bean, keys[i]);
39. bean = obj;
40. }//递归parse
41.
42. return obj;
43. }
44.
45. public static void main(String[] args){
46. UserBean bean = new UserBean();
47. bean.setName("John Abruzzi");
48. bean.setNick("Abruzzi");
49. bean.setAge(24);
50.
51. AddressBean addr = new AddressBean();
52. addr.setZip("0086");
53. addr.setStreet("Bell Street #12");
54. bean.setAddress(addr);
55.
56. System.out.println(BeanParser.doParse(bean, "bean.address.street"));
57. System.out.println(BeanParser.doParse(bean, "bean.address.zip"));
58. System.out.println(BeanParser.doParse(bean, "bean.name"));
59. System.out.println(BeanParser.doParse(bean, "bean.nick"));
60. System.out.println(BeanParser.doParse(bean, "bean.age"));
61. }
62. }

代码比较简短,重要部分有注释,应该很容易理解。当然这篇文章主要是关于Java的反射机制,如果需要对EL完全支持,可以使用JavaCC做一个简单的分析器(Apache的commons中包含一个el的项目,就是用javacc写的分析器)。

【编辑推荐】
1. 在Java应用程序中使用Jfreechart配置
2. Java程序员学习Flex和BlazeDS的十三个理由
3. 用JavaFX编写用户界面控制器
4. Java WEB开发中的中文乱码问题解决
5. 总结Java Web中几个函数的作用
【责任编辑:red7 TEL:(010)68476606】
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值