Java反射机制的一个实例

本文介绍如何使用Java反射机制实现简易EL表达式解析器,支持多级Bean属性访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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写的分析器)。

内容概要:《中文大模型基准测评2025年上半年报告》由SuperCLUE团队发布,详细评估了2025年上半年中文大模型的发展状况。报告涵盖了大模型的关键进展、国内外大模型全景图及差距、专项测评基准介绍等。通过SuperCLUE基准,对45个国内外代表性大模型进行了六大任务(数学推理、科学推理、代码生成、智能体Agent、精确指令遵循、幻觉控制)的综合测评。结果显示,海外模型如o3、o4-mini(high)在推理任务上表现突出,而国内模型如Doubao-Seed-1.6-thinking-250715在智能体Agent和幻觉控制任务上表现出色。此外,报告还分析了模型性价比、效能区间分布,并对代表性模型如Doubao-Seed-1.6-thinking-250715、DeepSeek-R1-0528、GLM-4.5等进行了详细介绍。整体来看,国内大模型在特定任务上已接近国际顶尖水平,但在综合推理能力上仍有提升空间。 适用人群:对大模型技术感兴趣的科研人员、工程师、产品经理及投资者。 使用场景及目标:①了解2025年上半年中文大模型的发展现状与趋势;②评估国内外大模型在不同任务上的表现差异;③为技术选型和性能优化提供参考依据。 其他说明:报告提供了详细的测评方法、评分标准及结果分析,确保评估的科学性和公正性。此外,SuperCLUE团队还发布了多个专项测评基准,涵盖多模态、文本、推理等多个领域,为业界提供全面的测评服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值