反射-概述

    xiaoxiao2025-08-09  6

    反射-概述

    概述获取Class对象的方式:演示: Class对象的常用功能

    整理回顾

    概述

    反射: 框架设计的灵魂 框架: 半成品软件,可以在框架的基础上进行软件开发,简化编码反射: 将类的各个组成部分封装为其他对象,这就是反射机制 反射的好处 可以在程序运行过程中,操作这些对象。可以解耦,提高程序的可扩展性。

    获取Class对象的方式:

    Class.forName("全类名") : 将字节码文件加载进内存,返回Class对象。 多用于配置文件,将类名定义在配置文件中。 读取文件,加载类。类名.class : 通过类名的属性class获取 多用于参数的传递对象.getClass() : getClass() 方法在Object类中定义着。 多用于对象的获取字节码的方式。

    演示:

    // 获取Class对象的三种方式 @Test public void test01() throws ClassNotFoundException { //1. Class.forName("全类名") Class cls1 = Class.forName("cn.fbd.demo.reflectDemo.domain.Persion"); System.out.println(cls1); //2. 类名.class 属性 Class cls2 = Persion.class; System.out.println(cls2); // 3. 对象.getClass() 方法 Persion p = new Persion(); Class cls3 = p.getClass(); System.out.println(cls3); }

    结论: 同一个字节码文件(*.class)再一次程序运行过程中,只会被加载一次,无论通过以上哪一种方式获取的Class对象都是同一个。

    Class对象的常用功能

    package cn.fbd.demo.reflectDemo; import cn.fbd.demo.reflectDemo.domain.Person; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class reflectClassTest { // 获取Class对象的三种方式 @Test public void test01() throws ClassNotFoundException { //1. Class.forName("全类名") Class cls1 = Class.forName("cn.fbd.demo.reflectDemo.domain.Person"); System.out.println(cls1); //2. 类名.class 属性 Class cls2 = Person.class; System.out.println(cls2); // 3. 对象.getClass() 方法 Person p = new Person(); Class cls3 = p.getClass(); System.out.println(cls3); System.out.println(cls1==cls2); System.out.println(cls1==cls3); } /** * */ @Test public void test02() throws NoSuchFieldException, IllegalAccessException { // 获取Persion的Class对象 Class persionClass = Person.class; /** * 1. 获取成员变量 public修饰的成员变量 * Field[] getFields() 所有的 * Field getField(String name) 指定名称的 * * Declared 暴力获取所有修饰符的成员变量 * Field[] getDeclaredFields() * Field[] getDeclareField(String name) */ // 获取所有public修饰的成员变量 Field[] fields = persionClass.getFields(); for (Field field: fields ) { System.out.println(field); } // 获取指定名称的public修饰的成员变量 Field a = persionClass.getField("a"); System.out.println(a); // 获取所有修饰符类型的成员变量 Field[] allFields = persionClass.getDeclaredFields(); for (Field fields2: allFields ) { System.out.println(fields2); } // 获取指定名称修饰符类型的成员变量 Field a2 = persionClass.getDeclaredField("name"); System.out.println(a2); // 在获取或者设置值之前要设置忽略访问权限修饰符的安全检查 a2.setAccessible(true); //---------- /** * 对成员变量Field的操作 * 1. 设置值 * void set(Object obj,Object value) * 2. 获取值 * get(Object obj) * 3. 忽略访问修饰符的安全检查 * setAccessible(true) 暴力反射 */ // 获取成员变量的值 Person p = new Person(); Object obj = a2.get(p); System.out.println(obj); // 设置成员变量的值 a2.set(p,"嘿嘿"); System.out.println(p); } /** * 获取构造方法 * @throws Exception */ @Test public void test03() throws Exception { Class personClass = Person.class; // 获取构造方法 有参构造 Constructor construtor1 = personClass.getConstructor(String.class,Integer.class,String.class); System.out.println(construtor1); // 创建对象 Object persion = construtor1.newInstance("老王", 23, "老铁"); System.out.println(persion); System.out.println("======================="); // 获取构造方法 无参构造 Constructor construtor2 = personClass.getConstructor(); System.out.println(construtor2); // 创建对象 Object persion2 = construtor2.newInstance(); System.out.println("常规的方式获取空参构造方法: "+persion2); // 使用简化的方式获取空参构造方法 Object o = personClass.newInstance(); System.out.println("简化的方式获取空参构造方法: "+o); } /** * // 获取成员方法 * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException */ @Test public void test04() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class person = Person.class; Method eat_method = person.getMethod("eat"); // 执行无参成员方法 Person p = new Person(); eat_method.invoke(p); // 执行有参数的成员方法 Method eat_method2 = person.getMethod("eat",String.class); eat_method2.invoke(p,"火鸡面!"); //------------------- //获取所有public修饰的方法 System.out.println("------------------------"); Method[] methods = person.getMethods(); for (Method method : methods ) { System.out.println(method); // 获取方法名 System.out.println(method.getName()); //method.setAccessible(true); } } }
    最新回复(0)