http://www.sxt.cn/u/482/blog/2498

反射机制

JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

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

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

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

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

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

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

然后是UserBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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写的分析器)。

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

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

==========

http://www.thinksaas.cn/group/topic/102025/

如何利用反射实现EL表达式相关推荐

  1. 利用EL表达式替换回车符

    后台数据库中数据格式: 要在页面以如下格式显示,即分号一换行: 首先想到在action中利用replaceAll来替换,于是写出如下代码: userlist.setPubmedmesh(rs.getS ...

  2. java 代码执行el,专属于java的漏洞——EL表达式注入

    前言"FSRC经验分享"系列文章,旨在分享焦点科技信息安全部工作过程中的经验总结,包括但不限于漏洞分析.运营技巧.sdl推行.等保合规.自研工具等等. 欢迎各位安全从业者持续关注~ ...

  3. JAVAWEB开发之Session的追踪创建和销毁、JSP详解(指令,标签,内置对象,动作即转发和包含)、JavaBean及内省技术以及EL表达式获取内容的使用

    Session的追踪技术 已知Session是利用cookie机制的服务器端技术,当客户端第一次访问资源时 如果调用request.getSession() 就会在服务器端创建一个由浏览器独享的ses ...

  4. JAVAWEB开发之Session的追踪创建和销毁、JSP具体解释(指令,标签,内置对象,动作即转发和包括)、JavaBean及内省技术以及EL表达式获取内容的使用...

    Session的追踪技术 已知Session是利用cookie机制的server端技术.当client第一次訪问资源时 假设调用request.getSession() 就会在server端创建一个由 ...

  5. el表达式 java_java基础学习:JavaWeb之EL表达式

    其他更多java基础文章: java基础学习(目录) 一.EL表达式 EL 全名为Expression Language.JSP中可以使用EL表达式,EL表达式是用"${}"括起来 ...

  6. EL表达式 (详解)

    表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法.它是一种简单的语言,基于可用的命名空间(PageContext 属性).嵌套属性和对集 ...

  7. Java-Web JSP指令、javabean和EL表达式

    目录 一.JSP指令 1.JSP指令概述 2.page指令 (1)pageEncoding和contentType (2)import (3)errorpage和isErrorpage (4)web. ...

  8. el表达式中换行_angularjs/ng-bind如何保留换行符

    达令说 不同于jquery只是一个加强和简化前端开发的类库,angularjs是一个完整web前端框架,所以学习曲线高了很多.angularjs给我的感觉类似于Java的Spring框架,处于中心容器 ...

  9. javaweb学习总结(二十九)——EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

最新文章

  1. 人工智能科普|极大似然估计——机器学习重要知识点
  2. Nacos 2.0 性能提升十倍,贡献者 80% 以上来自阿里之外
  3. echarts力导向图节点连线动画_基于 HTML5 网络拓扑图的快速开发之入门篇(一)...
  4. 2021东京奥运会数据接口
  5. [转]Git分支管理策略
  6. Ubuntu系统下ntp服务器搭建
  7. iOS10 Safari不识别viewport禁用缩放的暴力解决方案
  8. Python 之 循环
  9. golang MySQL 占内存_使用golang插入mysql性能提升經驗
  10. ssm基于WEB的房屋出租管理系统的设计与实现161620
  11. 专业网速测试软件哪个好,网速测试软件哪个好?6款热门网速测试软件推荐
  12. html修改页面图片大小,css怎么改变图片大小?
  13. matlab 代码 经典例题,MATLAB程序设计及经典例题解析3
  14. 网页前端培训(JavaScript)
  15. Mac如何找到和清理微信和QQ的缓存文件
  16. java学习-画图小程序
  17. Android程序锁的实现
  18. MMD新人学习记录博客1
  19. 多WAN路由器配置 实现简述
  20. 嵌入式市场四大热点及趋势

热门文章

  1. [知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能
  2. 【数据结构与算法】之深入解析“三数之和”的求解思路与算法示例
  3. Swift之深入解析枚举enum的底层原理
  4. G6 图可视化引擎——简介
  5. 【Linux】一步一步学Linux——unzip命令(68)
  6. Codeforces 987C. Three displays(o(n^2))
  7. linux网络编程-----几种服务器模型及io多路复用函数
  8. Android程序的基本组件
  9. 乐山电子计算机职业学院,学校介绍
  10. mysql删除表命令语句_MySQL增删改查语句命令(一)