• Java反射


    Java代码在计算机上的三阶段

    1. 源代码阶段。源代码经过编译,生成class文件
    2. Class类对象阶段。成员变量被封装为Field对象,构造函数被封装为Constructor对象,成员方法被封装为Method对象
    3. Runtime运行时阶段
    • 源代码阶段-->Class类对象阶段:ClassLoader将class加载进内存

    反射好处:

    1. 可以在程序的运行过程中,操作这些对象
    2. 可以解耦,提高程序的可拓展性

    获取Class对象的方式

    1. Class.ForName("全类名"):将字节码文件加载进内存,返回Class对象
      • 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
    2. 类名.class:通过类名的属性class获取
    3. 对象.getClass():getClass()方法在Object类中定义着
    • 注意:同一个字节码文件(*.class)在一次程序的运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

    Class对象功能

    获取功能

    1. 获取成员变量们
      • Field[] getFields():获取所有public修饰的成员变量
      • Filed getField(String name)
      • Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
      • Field getDeclaredField(String name)
    2. 获取构造方法们
      • Constructor<?>[] getConstructors()
      • Constructor getConstructor(类<?>... parameterTypes)// 参数举例:(String.class, int.class)
      • Constructor<?>[] getDeclaredConstructors()
      • Constructor getDeclaredConstructor(类<?>... parameterTypes)
    3. 获取成员方法们
      • Method[] getMethods()
      • Method getMethod(String name, 类<?>... parameterTypes)
      • Method[] getDeclaredMethods()
      • Method getDeclaredMethod(String name, 类<?>... parameterTypes)
    4. 获取类名
      • String getName()

    Filed:成员变量

    • 操作:
      1. 设置值
        • void set(Object obj, Object value)
      2. 获取值
        • get(Object obj)
      3. 忽略访问权限修饰符的安全检查
        • setAccssible(true):暴力反射

    Constructor:构造方法

    • 创建对象
      • T newInstance(Object... initargs)
      • 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

    Method:方法对象

    • 执行方法:
      • Object invoke(Object obj, Object... args)
      • String getName():获取方法的名称

    案例

    1. ReflectTest.java
    package com.study;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    public class ReflectTest {
    
        public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
    	// write your code here
    
            /**
             * 案例:写一个“框架”,在不改变类的任何代码的情况下,可以帮助我们创建任意类的对象,并且执行其中任意的方法
             * 实现:1.配置文件:
             *          ClassName=com.study.refelct.Dog
             *          MethodName=sleep
             *      2.反射
             * 步骤:1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
             *      2.在程序中加载读取配置文件
             *      3.使用反射技术来加载文件进内存
             *      4.创建对象
             *      5.执行方法
             */
            Properties properties = new Properties();
            ClassLoader classLoader = ReflectTest.class.getClassLoader();
            properties.load(classLoader.getResourceAsStream("pro.properties"));
    
            String className = properties.getProperty("ClassName");
            String methodName = properties.getProperty("MethodName");
    
            Class cls = Class.forName(className);
            Object obj = cls.newInstance();
            Method method = cls.getMethod(methodName);
            method.invoke(obj);
    
        }
    }
    
    1. Dog.java
    package com.study.refelct;
    
    public class Dog {
        public void sleep(){
            System.out.println("dog sleep...");
        }
    }
    
    
    1. pro.properties
    ClassName=com.study.refelct.Dog
    MethodName=sleep
    
  • 相关阅读:
    使用 Vim 搭建 JavaScript 开发环境
    SpaceVim 语言模块 erlang
    SpaceVim 语言模块 lua
    SpaceVim 语言模块 python
    SpaceVim 语言模块 elixir
    SpaceVim 语言模块 dart
    SpaceVim 语言模块 elm
    如何配置 SpaceVim
    彻底理解浏览器缓存机制
    react-创建react元素
  • 原文地址:https://www.cnblogs.com/hydc/p/16157632.html
Copyright © 2020-2023  润新知