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 { } 包括起来,捕获异常。