zoukankan      html  css  js  c++  java
  • Java基础一篇过(一)反射

    一、反射是个啥

      定义 : 在运行状态中动态获取类的信息以及动态调用对象的方法,这种功能称为java语言的反射机制。

    • 对于任意一个类,都能够知道这个类的所有属性和方法。
    • 对于任意一个对象,都能够调用它的任意一个方法和属性。

    二、Class对象

      定义 : 我们在开发过程中,创建的每一个类也是对象,即类本身是java.lang.Class类的实例对象,我们称这个实例对象为类对象,也就是Class对象。

      学习反射前我们先要了解类对象有什么用:

    • Class 类的实例对象表示正在运行的 Java 应用程序中的类和接口。
    • Jvm中有很多的实例,每个类都有唯一的Class对象。 Class 类没有公共构造方法。
    • Class 对象是在加载类时由 Java 虚拟机自动构造的。也就是说我们不需要创建,JVM已经帮我们创建了。
    • Class 对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法 。

      获取Class对象有以下几种方法:

    • Class.forName()(常用)
    • Test.class
    • new Test().getClass()
    /**
     * 反射机制demo
     */
    public class Test {
        public static void main(String args[]) throws Exception {
            /*获取类对象的三种方法*/
            //1、Class.forName()(常用)
            Class class1 = Class.forName("zhbf.web.Test");
            //2、Test.class
            Class class2 = Test.class;
            //3、new Test().getClass()
            Class class3 = new Test().getClass();
    
            /*三种方式创建的类对象调用其中的方法*/
            Method method1 = class1.getMethod("printSome",String.class);
            method1.invoke(class1, "class1");
            Method method2 = class2.getMethod("printSome",String.class);
            method2.invoke(class2, "class2");
            Method method3 = class3.getMethod("printSome",String.class);
            method3.invoke(class3, "class3");
        }
    
        public static void printSome(String className) {
            System.out.println(className + "通过反射机制获取方法并调用~");
        }
    }

    运行main方法:

    三、利用反射机制创建对象

    步骤:

    /*创建对象的流程*/
    //1.获取类对象
    Class classTest = Class.forName("zhbf.web.Test");
    //2.获取构造器对象(入参为选用的构造方法的参数类型)
    Constructor con = classTest.getConstructor();
    //3 获取对象
    Test test = (Test) con.newInstance();
    • getConstructors() :所有"公有的"构造方法
    • getDeclaredConstructors() :获取所有的构造方法(包括私有、受保护、默认、公有) 
    • getConstructor(构造方法的参数类型) :  获取单个的"公有的"构造方法
    • getDeclaredConstructor(构造方法的参数类型) : 获取"某个构造方法"可以是私有的,或受保护、默认、公有;
    • newInstance() : 获取对象

    四、获取成员变量并使用

    常用方法:

    • getField(属性名) : 只能获取public的,包括从父类继承来的字段
    • getDeclaredField(属性名) :  获取本类包括public、private和proteced的字段,但是不能获取继承来的字段
    • getDeclaredFields() : 获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段
    • setAccessible(布尔值): 设置变量是否可访问
    /*获取属性并修改*/
    ZhbfwebApplicationTests testClass = new ZhbfwebApplicationTests();
    //获取ZhbfwebApplicationTests类里访问权限为private的变量name
    Field field = Class.forName("zhbf.web.ZhbfwebApplicationTests").getDeclaredField("name");
    //设置变量可访问(ture)
    field.setAccessible(true);
    //上一步设置后,可对private的变量进行从新赋值
    field.set(testClass, "wlx");
    //打印从testClass对象里面获取的name变量
    System.out.println(field.get(testClass));

    五、获取成员方法并使用

    常用方法:

    • getMethod(方法名 ,入参类型)  : 获取"公有方法";(包含了父类的方法也包含Object类)
    • getDeclaredMethods(方法名 ,入参类型)  : 获取成员方法,包括私有的(不包括继承的)
    • invoke(对象,参数) : 调用方法
    //调用方法并传入参数
    Class class1 = Test.class;
    Method method = class1.getMethod("printSome", String.class);
    method.invoke(class1, "class1");

    六、反射的常见应用

      反射的常见应用场景如下:

    Spring框架的配置文件设计思想

      Spring框架的配置文件一般命名为application.properties,公用的配置一般都写在这里面,为什么要以这种方式来写入公共的信息呢?

      场景举例例如我们需要配置数据库连接信息:

    • 写在代码里,修改数据库连接地址就需要重新编译,相当麻烦
    • 写在配置文件里,利用反射机制读取,不用从新编译,只需要修改单独的配置文件内容就好。

    代码:

    /**
     * 反射机制读取文件
     */
    public class Test {
    
        public static void main(String args[]) throws Exception {
            //从application.properties中获取类名称和方法名称
            File springConfigFile = new File("E:\MyOwnGit\ZHBF\ZHBF-WEB\src\main\resources\application.properties");
            //Properties是Java语言的配置文件所使用的类,Xxx.properties为Java 语言常见的配置文件
            Properties springConfig = new Properties();
            //文件输入流读取文件内容
            springConfig.load(new FileInputStream(springConfigFile));
            String driverClass = (String) springConfig.get("spring.datasource.driver-class-name");
            String url = (String) springConfig.get("spring.datasource.url");
            String username = (String) springConfig.get("spring.datasource.username");
            String password = (String) springConfig.get("spring.datasource.password");
            System.out.println("=====输出数据库配置=====");
            System.out.printf("驱动类:%s url:%s 用户名:%s 密码:%s", driverClass, url, username, password);
        }
    
    }

    输出:

    修改配置文件后输出:

  • 相关阅读:
    Springmvc
    Mybatis关联关系
    Mybatis整合ehcache 和 redis
    Mybatis与spring集成
    MyBatis动态sql和分页
    MyBatis入门
    Vue模板语法(二)
    Vue模板语法(一)
    Spring---SSH整合(二)
    Spring---SSH整合
  • 原文地址:https://www.cnblogs.com/riches/p/12069323.html
Copyright © 2011-2022 走看看