8、Java反射(8. Java reflection)

一句话概括就是使用反射可以赋予jvm动态编译的能力,否则类的元数据信息只能用静态编译的方式实现,例如热加载,Tomcat的classloader等等都没法支持。

实现Java反射机制的类都位于java.lang.reflect包中:

  • Class类:代表一个类
  • Field类:代表类的成员变量(类的属性)
  • Method类:代表类的方法
  • Constructor类:代表类的构造方法
  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法
@Test
    private void test008() throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, IllegalAccessException {
        //第一种方式获取Class对象
        Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
        Class stuClass = stu1.getClass();//获取Class对象
        log.debug(stuClass.getName());

        //第二种方式获取Class对象
        Class stuClass2 = Student.class;
        log.debug(String.valueOf(stuClass == stuClass2));
        //判断第一种方式获取的Class对象和第二种方式获取的是否是同一个

        //第三种方式获取Class对象
        try {
            Class stuClass3 = Class.forName("com.kolaer.cms.CmsApplicationTests.Student");
            //注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
            log.debug(String.valueOf(stuClass3 == stuClass2));
            //判断三种方式是否获取的是同一个Class对象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        log.debug("*****************获取公有、无参的构造方法*************");
        Constructor con = stuClass.getConstructor(null);
        //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
        //2>、返回的是描述这个无参构造函数的类对象。
        log.debug("*************获取公有字段**并调用*****************");
        Field f = stuClass.getField("name");
        log.debug(String.valueOf(f));


        log.debug("***************获取私有的show4()方法******************");
        Method m = stuClass.getDeclaredMethod("getUsername", String.class);
        log.debug(String.valueOf(m));
        m.setAccessible(true);//解除私有限定
        Object result = m.invoke(stu1, "zhangsan");//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
        log.debug("返回值:" + result);

    }
————————

In a word, reflection can give the JVM the ability of dynamic compilation. Otherwise, the metadata information of the class can only be implemented by static compilation, such as hot loading, Tomcat classloader and so on.

The classes that implement the java reflection mechanism are located in Java In lang.reflect package:

  • Class: represents a class
  • Field class: represents the member variables of the class (properties of the class)
  • Method class: represents the method of the class
  • Constructor类:代表类的构造方法
  • Array class: provides static methods for dynamically creating arrays and accessing array elements
@Test
    private void test008() throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, IllegalAccessException {
        //第一种方式获取Class对象
        Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
        Class stuClass = stu1.getClass();//获取Class对象
        log.debug(stuClass.getName());

        //第二种方式获取Class对象
        Class stuClass2 = Student.class;
        log.debug(String.valueOf(stuClass == stuClass2));
        //判断第一种方式获取的Class对象和第二种方式获取的是否是同一个

        //第三种方式获取Class对象
        try {
            Class stuClass3 = Class.forName("com.kolaer.cms.CmsApplicationTests.Student");
            //注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
            log.debug(String.valueOf(stuClass3 == stuClass2));
            //判断三种方式是否获取的是同一个Class对象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        log.debug("*****************获取公有、无参的构造方法*************");
        Constructor con = stuClass.getConstructor(null);
        //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
        //2>、返回的是描述这个无参构造函数的类对象。
        log.debug("*************获取公有字段**并调用*****************");
        Field f = stuClass.getField("name");
        log.debug(String.valueOf(f));


        log.debug("***************获取私有的show4()方法******************");
        Method m = stuClass.getDeclaredMethod("getUsername", String.class);
        log.debug(String.valueOf(m));
        m.setAccessible(true);//解除私有限定
        Object result = m.invoke(stu1, "zhangsan");//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
        log.debug("返回值:" + result);

    }