3.2 反射
我们通常写的程序都是静态的代码,比如:调用class A示例的put方法:
A a = new A(); a.put(“Hello!”);
第二行,a.put就是一种静态的写法。在编译阶段,就完成对a类型的解析,对a是否具有put方法进行了判断。如果a对象没有put方法,则编译不通过。
可是,在一些特殊情况下,我们需要在运行时动态地对一个对象的指定方法进行调用,比如我们想写一个通用的函数,传入一个对象,把这个对象的属性名和属性值都打印出来,这就需要使用反射技术。
反射,是在JDK 1.5引入的,JDK 1.4以及以前的版本不支持。
在java.lang.reflect包中,定义了一些类,用于运行时动态解析和调用对象,常用的如下:
● Constructor :构造函数
● Field :成员变量
● Method :成员方法
● Type :类型
另外,java.lang包中,Class类是非常值得重视的,通常用它来动态创建对象。对于声明了无参数的构造函数,或者有默认构造函数的类,动态创建一个对象的代码如下:
Class cls = Class.forName(“com.test.ServiceImpl”); Object obj = cls.newInstance();
这样,一个com.test.ServiceImpl类的实例就创建出来了。
假如ServiceImpl类有个registerUser方法,实现用户注册功能,如下:
public int registerUser(String userName, String passwd);
如何动态调用呢?代码示例如下:
// 动态加载类 Class cls = Class.forName("com.test.ServiceImpl"); // 动态创建对象 Object obj = cls.newInstance(); // 获取相应的方法 Method method = cls.getDeclaredMethod("registerUser", String.class, String.class); String userName = "zhangsan"; String passwd = "hello123"; // 动态调用对象的方法 Object result = method.invoke(obj, new Object[] {userName, passwd});
// 强制类型转换,获取函数调用的返回值 int userId = ((Integer)result).intValue(); System.out.println("userId=" + userId);
以上代码,需用try { } 包括起来,捕获异常。