Java反射

反射:框架设计的灵魂

        框架:半成品软件。可以在框架的基础上进行软件开发,简化编码

反射概念:

        将类的各个组成部分封装为其他对象,这就是反射机制

         好处:

                可以在程序运行中操作这些对象

                可以解耦,提高程序的可扩展性

获取Class对象的方式

        1.Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

                *多用于配置文件,将类名定义在配置文件中。获取文件,加载类

        2.类名.class:通过类名的属性class来获取

                * 多用于参数的传参

        3.对象.getClass():getClass()方法在Object类中定义着。

                * 多用于对象的获取字节码的方式

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

        

package com.aaa.springboot;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:06
 */
public class TestDemo {
    public static void main(String[] args) throws Exception {
      //1.Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
        Class<?> cls1 = Class.forName("com.aaa.springboot.Person");
        System.out.println(cls1);


       // 2.类名.class:通过类名的属性class来获取
        Class cls2 = Person.class;
        System.out.println(cls2);

      //  3.对象.getClass():getClass()方法在Object类中定义着。
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);

        // ==  比较对象
        System.out.println(cls1 == cls2); // true
        System.out.println(cls1 == cls3); // true
        System.out.println(cls2 == cls3); // true

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

    }
}

使用Class对象功能:

        获取功能:

                1.获取成员变量们       

                *Field[] getFields(): 获取所有 public修饰的成员变量
                *Field getField(String name):获取指定名称的 public修饰的成员变量
                *Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
                *Field  getDeclaredField(String name)

                2.获取构造方法们

                        *getConstructors()

                        *getConstructor(Class<?>…parameterTypes)

                        *getDeclaredConstructors()

                        *getDeclaredConstructor(Class<?>...parameterTypes)

                3.获取成员方法们

                        *getMethods()

                        *getMethods(String name,Class<?> …parameterTypes)

                        *getDeclaredMethods()

                        *getDeclaredMethods(String name,Class<?>...parameterTypes)

                4.获取类名

                        * String getName()

Field:成员变量使用

        操作:

                1.设置值

                        * void set(Object obj,Object value)

                2.获取值

                        * get(Object obj)

                3. 忽略访问权限修饰符的安全检测      

             * .setAccessible(true);// 暴力反射
package com.aaa.springboot;

import java.lang.reflect.Field;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:57
 */
public class ReflectDemo {
      
    public static void main(String[] args) throws Exception {
        //获取 Person的Class对象
        Class personClass = Person.class;
/*        1.获取成员变量们
                *Field[] getFields(): 获取所有 public修饰的成员变量
                *Field getField(String name):获取指定名称的 public修饰的成员变量
                *Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
                *getDeclaredField(String name)
*/
        //Field[] getFields()
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("------------------");
        Field a = personClass.getField("a");
        // 获取成员变量 a 的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);
        // 设置 a的值
        a.set(p,"张三");
        System.out.println(p);
        System.out.println("====================================");

        // Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        System.out.println("====================================");
        // Field  getDeclaredField(String name)
        Field age = personClass.getDeclaredField("age");
        // 忽略访问权限修饰符的变量检查
        age.setAccessible(true);// 暴力反射
        Object value2 = age.get(p);
        System.out.println(value2);
    }
}

Constructor:构造方法使用

        创建对象:  

        * T newInstance(Object... initargs)

                * 如果用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

package com.aaa.springboot;

import java.lang.reflect.Constructor;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:57
 */
public class ReflectDemo2 {
      

    public static void main(String[] args) throws Exception {
        //获取 Person的Class对象
        Class personClass = Person.class;
/*
        获取构造方法们
         *getConstructors()

         *Constructor<T> getConstructor(类<?>... parameterTypes)

         *getDeclaredConstructors()

         *getDeclaredConstructor(Class<?>...parameterTypes)
*/

        //Constructor<T> getConstructor(类<?>... parameterTypes)
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        System.out.println(constructor);

        //创建对象
        Object person = constructor.newInstance("张三", 23);
        System.out.println(person);
        System.out.println("------------------------");

        Constructor constructor1 = personClass.getConstructor();
        System.out.println(constructor);
        //创建对象
        Object person1 = constructor1.newInstance();
        System.out.println(person1);


        Object o = personClass.newInstance();
        System.out.println(o);
    }
}

Method : 方法对象

        执行方法:

                * Object invoke(Object obj,Object... args)

        获取方法名称:

                * String getName  获取方法名、

package com.aaa.springboot;

import java.lang.reflect.Method;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:57
 */
public class ReflectDemo3 {

    public static void main(String[] args) throws Exception {
        //获取 Person的Class对象
        Class personClass = Person.class;
/*
          3.获取成员方法们
         *getMethods()

         *getMethods(String name,Class<?> …parameterTypes)

         *getDeclaredMethods()

         *getDeclaredMethods(String name,Class<?>...parameterTypes)
*/

        // 获取指定名称的方法
        Method eat_method1  = personClass.getMethod("eat");
        Person p = new Person();
        //执行方法
        eat_method1.invoke(p); //空参方法

        System.out.println("--------------以下是有参-------------");
        Method eat_method2 = personClass.getMethod("eat", String.class);
        //执行方法
        eat_method2.invoke(p,"卧槽");

        System.out.println("--------------一下是获取public修饰的方法 包括Object方法----------------");
        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            //获取方法名
            String name = method.getName();
            System.out.println(name);
        }

    }
}

获取类名:

        

package com.aaa.springboot;



/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:57
 */
public class ReflectDemo3 {

    public static void main(String[] args) throws Exception {
        //获取 Person的Class对象
        Class personClass = Person.class;
/*
         4.获取类名
            * String getName()
*/

        //获取类名
        String name = personClass.getName();
        System.out.println(name);

    }
}

        

案例:

        需求:写一个”框架“  不行真正的框架 带引号 哈哈哈 ,可以帮我们创建任意类的对象,并且执行其中任意方法

        实现:

                1.配置文件

                2.反射

        步骤:

                1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中

                2.在程序中加载读取配置文件

                3.使用反射技术来加载文件进内存

                4.创建对象

                5.执行方法

   第一步              

package com.reflect;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 14:05
 */
public class Person {

    public void eat(){
            System.out.println("xxxxx");
        }

}
package com.reflect;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 15:59
 */
public class Student {
    public void sleep(){
        System.out.println("sleep...");
    }
}

 第二步     在src创建一个配置文件

 

className=com.reflect.Person
methodName=eat

#className=com.reflect.Student
#methodName=sleep

  第三步     

package com.reflect;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @version 1.0
 * @author:张先生
 * @description:
 * @date 2022/8/13 16:00
 */

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        // 可以创建任意类的对象,可以执行任意方法
    /*
        前提,不能改变该类的任何代码,可以创建任意类的对象,可以执行任意方法
    */
/*        Person p = new Person();
        p.eat();
*/
/*

        Student stu = new Student();
        stu.sleep();
*/

        //1.加载配置文件
        // 1.1 创建Properties对象
        Properties pro = new Properties();
        // 1.2 加载配置文件,转换为一个集合
        // 1.2.1 获取class目录下的配置文件的方式
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        pro.load(is);

        //2. 获取配置文件中定义的数据
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        //3. 加载该类进内存
        Class cls =Class.forName(className);
        //4. 创建对象

        Object obj = cls.newInstance();

        //5. 获取方法对象
        Method method = cls.getMethod(methodName);
        //6. 执行方法
        method.invoke(obj);
    }

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值