`

Java反射机制的一个实例 from abruzzi javaeye

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

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"));  
} 

需要可以输出:
Bell Street #12 
0086 
John Abruzzi  
Abruzzi  
24 


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

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

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

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

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
ackage elparser; 

public class UserBean { 
    private String name; 
    private String nick; 
    private AddressBean address; 
    private int age; 
     
    public int getAge(){ 
        return this.age; 
    } 
     
    public void setAge(int age){ 
        this.age = age; 
    } 
     
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
    public String getNick() { 
        return nick; 
    } 
    public void setNick(String nick) { 
        this.nick = nick; 
    } 
    public AddressBean getAddress() { 
        return address; 
    } 
    public void setAddress(AddressBean address) { 
        this.address = address; 
    } 
}


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

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


kage elparser;  
 
import java.lang.reflect.Method;  
 
public class BeanParser {  
      
    private static String getMethodName(String property, String prefix){  
        String prop = Character.toUpperCase(property.charAt(0))+property.substring(1);  
      
        String methodName = prefix + prop;  
      
        return methodName;  
    }  
      
    private static Object parse(Object bean, String expr){  
        Class beanClass = bean.getClass();  
          
        Method method = null;  
        Object result = null;  
          
        try{  
            //这两步是关键,get方法不需要传入参数,所以只是new出两个空数组传入  
            method = beanClass.getMethod(getMethodName(expr, "get"), new Class[]{});  
            result = method.invoke(bean, new Object[]{});  
        }catch(Exception e){  
            System.out.println(e.getMessage());  
        }  
          
        return result;  
    }  
      
    public static Object doParse(Object bean, String expr){  
        String keys[] = expr.split("\\.");  
          
        Object obj = null;  
          
        for(int i = 1; i < keys.length;i++){  
            obj = parse(bean, keys[i]);  
            bean = obj;  
        }//递归parse  
          
        return obj;  
    }  
      
    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"));  
    }  
} 
分享到:
评论

相关推荐

    一个动态的Tip的实现

    NULL 博文链接:https://abruzzi.iteye.com/blog/306242

    一个实用的JS对表格的特效

    NULL 博文链接:https://abruzzi.iteye.com/blog/299305

    letusgo-team-c:让我们去申请C队

    Let's Go 服务器的基线这是一个简单的 RESTFul 服务器,用于 Let' Go 在线商店服务器,它现在是用 Ruby 编写的。 它包含一些快速开始 Web 开发的基本部分。 作为 Web 服务器作为 ORM Sqlite3 作为数据库(单文件...

    letusgo-team-b:让我们去申请B队

    Let's Go 服务器的基线这是一个简单的 RESTFul 服务器,用于 Let' Go 在线商店服务器,它现在是用 Ruby 编写的。 它包含一些快速开始 Web 开发的基本部分。 作为 Web 服务器作为 ORM Sqlite3 作为数据库(单文件...

    letusgo-team-a:让我们去申请A队

    Let's Go 服务器的基线这是一个简单的 RESTFul 服务器,用于 Let' Go 在线商店服务器,它现在是用 Ruby 编写的。 它包含一些快速开始 Web 开发的基本部分。 作为 Web 服务器作为 ORM Sqlite3 作为数据库(单文件...

    vim命令简表

    NULL 博文链接:https://abruzzi.iteye.com/blog/416049

    reveal-tw-boilerplate:Reveal.js 与 ThoughtWorks 新 VI

    一个非常简单的 Reveal.js 模板 对于那些只想创建新幻灯片的人 git clone然后在浏览器中打开 index.html,就是这样。 其实你可以更进一步,试着生动地编辑你的幻灯片(见下面的部分)。 $ git clone git@github....

    iscc01-wpcap.pdf

    An Architecture for High Performance Network Analysis Fulvio Risso and Loris Degioanni Dipartimento di Automatica e Informatica – Politecnico di Torino Corso Duca degli Abruzzi, 24 – 10129 ...

    mommify-test:TDD 实践

    文件中有 2 个占位符: &lt;!-- include source files here... --&gt; &lt;!-- include spec files here... --&gt; 您应该记住的一件事是, source代码应该在针对它的specification测试BEFORE放置。 玩得开心!

    tw-testable-[removed]ThoughtWorks内部培训代码库

    git clone git@github.com:abruzzi/tw-testable-javascript.git 并初始化环境: cd tw-testable-javascript bower install 安装完成后,您应确保后端服务按预期工作: curl ...

Global site tag (gtag.js) - Google Analytics