13.反射原理及示例

自从Jdk1.5推出了反射,java从一种静态语言变为一种动态语言了。可以动态调用方法的具体方法、实现等等,一下高端大气上档次起来。

1、反射是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2、反射机制能做什么

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;

3、反射机制的相关API及使用

代码参见com.critc.ReflectTest

/**
 * Created by 孔垂云 on 2017/4/17.
 * 通过一个对象获得完整的包名和类名
 */
public class ReflectTest {

    public static void main(String[] args) throws Exception {
        //通过一个对象获得完整的包名和类名
        ReflectTest testReflect = new ReflectTest();
        System.out.println(testReflect.getClass().getName());
        // 结果 com.critc.ReflectTest


        //实例化Class类对象
        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;
        // 一般采用这种形式
        class1 = Class.forName("com.critc.ReflectTest");
        class2 = new ReflectTest().getClass();
        class3 = ReflectTest.class;
        System.out.println("类名称   " + class1.getName());
        System.out.println("类名称   " + class2.getName());
        System.out.println("类名称   " + class3.getName());


        //获取某个类的全部属性
        Class<?> clazz = Class.forName("com.critc.vo.User1");
        System.out.println("===============本类属性===============");
        // 取得本类的全部属性
        Field[] field = clazz.getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
            // 权限修饰符
            int mo = field[i].getModifiers();
            String priv = Modifier.toString(mo);
            // 属性类型
            Class<?> type = field[i].getType();
            System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
        }

        //获取某个类的全部方法
        Class<?> clazz2 = Class.forName("com.critc.vo.User1");
        Method method[] = clazz2.getMethods();
        System.out.println("==========所有方法如下:=========");
        for (int i = 0; i < method.length; ++i) {
            Class<?> returnType = method[i].getReturnType();
            Class<?> para[] = method[i].getParameterTypes();
            int temp = method[i].getModifiers();
            System.out.print(Modifier.toString(temp) + " ");
            System.out.print(returnType.getName() + "  ");
            System.out.print(method[i].getName() + " ");
            System.out.print("(");
            for (int j = 0; j < para.length; ++j) {
                System.out.print(para[j].getName() + " " + "arg" + j);
                if (j < para.length - 1) {
                    System.out.print(",");
                }
            }
            Class<?> exce[] = method[i].getExceptionTypes();
            if (exce.length > 0) {
                System.out.print(") throws ");
                for (int k = 0; k < exce.length; ++k) {
                    System.out.print(exce[k].getName() + " ");
                    if (k < exce.length - 1) {
                        System.out.print(",");
                    }
                }
            } else {
                System.out.print(")");
            }
            System.out.println();
        }

        System.out.println("==========调用类的方法===========");
        //调用类的方法
        Class<?> clazz3 = Class.forName("com.critc.vo.User1");
        Method method3 = clazz3.getMethod("setId", int.class);
        //method3.invoke(clazz.newInstance());//先调用new方法
        method3.invoke(clazz3.newInstance(), 20);//调用set方法

        User1 user1 = new User1("测试", 10, "123");
        Class clazz4 = user1.getClass();
        Method method4 = clazz4.getDeclaredMethod("getName");
        String name = (String) method4.invoke(user1);//调用get方法
        System.out.println(name);
    }
}

应用场景主要包括以下:

1、参数替换,比如一段文字里面的参数${id},${name}等,传过来一个对象,就可以先用正则表达式获取这些参数,然后调用参数的get方法
2、动态调用一些列的方法,比如两个类都继承一个接口,要根据参数来判断调用哪个类的哪个方法,就可以动态调用了。
3、spring里面的BeanFactory,最常用的,后面会单独讲

源码下载

本例子详细源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容