- 浏览: 452781 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
进退取舍:
谢谢,这个用上了!!
Java 一个线程池的示例 -
pb_water:
感谢楼主,打算买楼主的书,支持一下,楼主功德无量
JavaScript内核系列第0版整理稿下载 -
lancezhcj:
有图会直观的多呢,再摸索摸索
有限自动机与建模 -
hsmsyy:
这里应该是原创了吧,楼主我觉得闭包的作用:实现面向对象。有待商 ...
JavaScript内核系列 第7章 闭包 -
wll52:
在应用退出之前,需要释放连接 con.disconnect() ...
使用smack与GTalk通信
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到容器中的。
我们从容器中取出以bean为名字的Object,通过反射知道它的真实类型,然后通过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
package 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
好了,看看怎么通过一个串和一个对象来取出其中的字段来:
package 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")); } }
代码比较简短,重要部分有注释,应该很容易理解。当然这篇文章主要是关于Java的反射的,如果需要对EL完全支持,可以使用JavaCC做一个简单的分析器(Apache的commons中包含一个el的项目,就是用javacc写的分析器)。
评论
6 楼
abruzzi
2009-04-09
JavaBean中的getter/setter属于JavaBean规范的一部分,JSP/EL等中对bean的引用就可以基于这个规范来做,这个是最重要的。而且,如eclipse之类的IDE都可以自己生成getter/setter,所以代码量倒还不是很大。
我的代码目前对boolean的支持不够标准,谢谢提出,我有时间再好好改一下,呵呵。
我的代码目前对boolean的支持不够标准,谢谢提出,我有时间再好好改一下,呵呵。
5 楼
litian33
2009-04-09
我们在项目中用到反射比较多,不过我现在很少使用方法来操作了,个人感觉JavaBean中的setXXX和getXXX有点多余(可以是接触脚本语言太多了吧)
我的做法是直接getField(xxx),然后setAccessible(true),就可以get了,这样写代码会少,也会清晰点(最起码不用组装方法名了,楼主的代码处理不了boolean属性)
我的做法是直接getField(xxx),然后setAccessible(true),就可以get了,这样写代码会少,也会清晰点(最起码不用组装方法名了,楼主的代码处理不了boolean属性)
4 楼
elvishehai
2009-04-09
还不错哦!
3 楼
childrentown
2009-04-09
如果用户们都使用JavaBean命名规范的话就最好了,可惜有的用户比较那个,什么都不按规范,不按套路出牌。不过这个工具还是很好用的,呵呵
2 楼
abruzzi
2009-04-03
正是来源于实际项目,呵呵。最近在做一个部分支持EL规范的工具。
1 楼
GonnaFlyNow
2009-04-03
这个工具类真不错,项目中应该可以用到
发表评论
-
JavaScript内核系列 第15章 服务器端的JavaScript
2012-02-12 21:39 2335第15章已经在icodeit上发布,这一章分为上/下两篇,请朋 ... -
使用vim开发python及graphviz绘图
2011-12-23 14:49 6463基本需求 使用vim中的autocmd命令可以很容易的将正在 ... -
Java脚本技术应用实例
2011-01-22 11:24 4276前言 一直以来都很喜欢可以自由扩展的软件,这一点应该已经在很 ... -
可编程计算器(phoc)的设计与实现
2011-01-17 11:34 1989前言 借助JavaScript脚本 ... -
函数式编程(javascirpt)
2009-04-18 22:18 1275前言 Javascript,有人称 ... -
C和指针
2009-05-21 23:15 1122前言 指针是C的灵魂,正是指针使得C存在了这么多年,而且将长 ... -
C和指针(续)
2009-05-25 23:41 1363前言 上一篇《C和指针》可能对关于C和指针的有些内容没有说透 ... -
有限自动机与建模
2009-06-06 10:48 1793前言 在学校学程序设计语言的时候,能接触到的所有例子没有一个 ... -
事件和监听器
2009-06-21 22:06 1441前言 事件监听器是经 ... -
基于总线的消息服务(BBMS)的设计与实现
2009-07-25 22:19 1367前言 异步事件的通知机制在比较有规模的软件设计中必然会有涉及 ... -
JavaScript内核系列 第9章 函数式的Javascript
2010-05-13 19:20 3790第九章 函数式的Javascript 要说Ja ... -
JavaScript内核系列 第8章 面向对象的JavaScript(下)
2010-05-06 09:40 3675接上篇:JavaScript内核系列 第8章 面向对象的Jav ... -
JavaScript内核系列 第8章 面向对象的JavaScript(上)
2010-05-06 09:26 2914第八章 面向对象的 Javascript ... -
JavaScript内核系列 第7章 闭包
2010-05-04 08:48 3885第七章 闭包 闭包向来给包括JavaScript程序 ... -
JavaScript内核系列 第6章 正则表达式
2010-04-27 19:44 4060第六章 正则表达式 正则表达式是对字符串的结构 ... -
JavaScript内核系列 第5章 数组
2010-04-24 15:17 4543第五章 数组 JavaScript的数组也是一个比较 ... -
Swing小应用(Todo-List)之三
2010-04-22 20:47 2138前言 去年9月份开发的那个小工具sTodo,只是做到了能用, ... -
JavaScript内核系列 第4章 函数
2010-04-18 17:31 5098第四章 函数 函数,在C语言之类的过程式语言中 ... -
JavaScript内核系列 第3章 对象与JSON
2010-04-12 09:12 6148第三章 对象与JSON JavaScript对象与传 ... -
JavaScript内核系列 第2章 基本概念
2010-04-03 19:44 5705第二章 基本概念 ...
相关推荐
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。通过反射,开发者可以在程序执行时发现并访问类的字段(fields)、方法(methods)以及构造器(constructors),...
下面通过一个简单的示例来展示Java反射机制的工作流程: ```java import java.lang.reflect.*; public class DumpMethods { public static void main(String args[]) { try { Class c = Class.forName(args[0])...
Java反射机制是Java语言的一个重要特性,它允许程序在运行时获取类的信息并操作对象。Java反射机制的主要作用包括:获取类的所有属性和方法、构造动态实例、调用类的方法等。通过反射,程序可以动态地创建对象和调用...
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...
以下是对Java反射机制应用实例的详细解释: 1. **获取类信息**:使用`Class`类的`forName()`方法可以获取到任何类的`Class`对象,例如`Class<?> clazz = Class.forName("全限定类名");`。这样我们就能获取到该类的...
Java 反射机制详解 Java 反射机制是 Java 语言提供的一种强大的工具,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并进行操作。这种能力使得 Java 应用程序更加灵活,能够在运行时发现和修改自身...
Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中在java.lang.reflect包下,包括Class、Constructor、Method和...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法等对象。这一机制对于理解和利用Java的动态性至关重要,尤其是在进行复杂系统设计、框架开发以及元数据驱动的应用中...
1.通过Java反射机制获取JavaBean对象。 2.通过JavaBean全路径字符串获取JavaBean对象。 3.获取JavaBean注解信息
### Java反射机制总结 ...总之,Java反射机制是Java语言的一个重要特性,它提供了在运行时动态获取类信息和操作类结构的能力。合理使用反射可以提高程序的灵活性和扩展性,但在使用时也需要考虑到其潜在的问题和限制。
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个实例将深入探讨Java反射机制的使用,通过具体代码示例来阐述其工作原理和应用。 在Java中...
Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。...
在"Java反射机制学习(二)"这篇博文中,作者可能详细解释了以上这些概念,并通过`BaseTest.java`和`Student.java`这两个示例文件进行了实例演示。`BaseTest.java`可能包含了一组基础的反射操作,而`Student.java`...
通过上述实例,我们可以看到Java反射机制在许多实际场景中的应用,它扩展了Java代码的灵活性和可扩展性。然而,也应注意,过度使用反射可能会引入复杂性和潜在的安全风险,因此在设计和实现时需权衡利弊。在理解了...