反射机制是JAVA的高级特性,那什么是JAVA反射机制呢?
JAVA反射机制都是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
动态获取类的信息主要包含以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理。
反射机制相关包是java.lang.reflect.*
下面实现简单的Spring Ioc来列举反射机制的简单实例
Spring Ioc(Inverse of Control) 控制反转,通过注入来实现实例创建,而不是通过new来指定对象。Ioc的应用大大减少了代码的耦合性,文本简单模拟一个Ioc通过配置文件注入实例。什么是控制反转以及依赖注入推荐参照书籍《Spring in Action》
public interface Action { public String execute(String str); }
public class UpperAction implements Action { private String message; public String getMessage() { return message; } public void setMessage(String string) { message = string; } public String execute(String str) { return (getMessage() + str).toUpperCase(); } }
public class LowerAction implements Action { private String message; public String getMessage() { return message; } public void setMessage(String string) { message = string; } public String execute(String str) { return (getMessage() + str).toLowerCase(); } }
public class ActionFactory { public static Action getAction(String actionName) { Properties prop = new Properties(); try { ClassLoader loader = ActionFactory.class.getClassLoader(); prop.load(loader.getResourceAsStream("config.properties")); String actionImplName = (String) prop.get(actionName); String actionMessage = (String) prop.get(actionName + "_msg"); Class cl = Class.forName(actionImplName); Object obj = cl.newInstance(); // 反射机制获取域参数并为域参数值注入值 Field[] fields = cl.getDeclaredFields(); Field field = fields[0]; String fieldName = field.getName(); String firstLetter = fieldName.substring(0, 1).toUpperCase(); String setMethodName = "set" + firstLetter + fieldName.substring(1); Method setMethod = cl.getMethod(setMethodName, new Class[] { field.getType() }); setMethod.invoke(obj, new Object[] { actionMessage }); return (Action) obj; } catch (Exception e) { e.printStackTrace(); } return null; } }
读取的配置文件如下
TheAction=test.UpperAction TheAction_msg=Hello
测试执行类如下
public class TestAction{ public static void main(String[] args) { Action action = ActionFactory.getAction("TheAction"); System.out.println(action.execute(“ World ")); } }
输出结果
HELLO WORLD
本次实例的Action返回对象存在依赖关系,可以通过泛型或者Object来替换Action返回值来对工场进行优化,使得其对具体的类不存在耦合性。但是本文的关键部分是说明java反射机制应用,ActionFactory中应用到反射机制来获取newInstance构造出来的实例的域对象,即实例对象的属性值,然后通过命名约束,利用invoke方法执行setter方法对参数进行赋值。