zoukankan      html  css  js  c++  java
  • Java的反射技术

    什么是反射机制

    Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意属性和方法。这种动态获取信息以及动态调用对象属性和方法的即使称为Java的反射机制。

    反射的应用场景

    在编译时根本无法知道该类或对象可能属于哪些类,程序只能依靠运行时信息来发现该类和对象的真实信息。、

    反射的作用

    通过反射可以使程序代码访问装载到JVM中的类的内部信息。
    获取已装载类的属性信息
    获取已装载类的方法
    获取已装载类的构造方法信息
    在JDK中,反射机制主要通过以下类来实现的,这些类除了Class类以外都位于java.lang.reflect包中
    java.lang.Class <T> 类
    java.lang.reflect.Field 类
    java.lang.reflect.method 类
    java.lang.reflect.Constructor <T> 类

    java.lang.Class <T> 类

    1)Class类是Java反射机制的起源和入口

    Class类继承自Object类

    用于获取与类相关的各种信息

    提供了获取类信息的相关方法

    2)Class类是所有类的共同的图纸

    每个类都有自己的对象,好比图纸和实物的关系

    每个类也可以看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应信息

    类的名字

    属性

    方法

    构造方法

    父类和接口

    3)Class类的常用方法

    getFields()  // 获得类的public类型的属性
    getDeclaredFields()  // 获得类的所有属性
    getField(String name)  // 获得类的指定属性
    getMethods()  // 获得类的public类型的方法
    getMethos(String name, Class<?>...parameterTypes)  // 获得类的指定方法
    getConstructors()  // 获得类的public类型的构造方法
    getConstructor(Class<?>...parameterTypes)  // 获得类的指定的构造方法
    getName()  // 获得类的完成的名字
    getpackage()  // 获得此类所属的包
    getSuperclass()  // 获得此类的父类对应的Class实例对象
    isArray() // 判断该类型是否是数组
    isEnum() // 判断该类型是否是接口
    isInterface() // 判断该类型是否是接口
    isPrimitive() // 判断该类型是否是基本数据类型(8种基本数据类型) newInstance()
    // 通过类的无惨构造方法创建一个对象

    4)获取类的Class实例对象的方法(可分为三类)

    Class.forName(“类的全限定名”)  // 调用Class类的静态方法,该方法将装载类,并做类的静态初始化,返回一个Class类的实例对象
    类名.class  // JVM将使用类装载器,将类装入内存(前提是类还没有转入内存),不做类的初始化工作,返回类的Class的对象实例。
    包装类.TYPE  // 包装类的Class类型的静态常量,可以得到相应基本数据类型的Class实例对象
    对象名.getClass()  // Object类的方法,对垒进行静态初始化,非静态初始化,返回代表该对象的运行时类的Class实例对象
    对象名.getSuperclass  //  Class类的方法,返回该对象的父类的Class类实例对象

    说明:类的静态属性和方法的初始化是在加载类的时候完成了;而类的非静态属性和方法的初始化时在new一个实例对象的时候完成的。

    当我们编译一个新的Java类时,JVM就会帮我们编译成Class对象实例,存放在类名.class文件中。在运行时,当需要生成这个类的对象时,JVM就会检查这个类是否已经装载到内存中,若没有装载,则把类名.class文件装载到内存,若已经加载了,则根据类名.class文件生成Class实例对象。

    在Java中,任何一个类都会有一个Class实例对象与之对应,在这个Class对象中,保存着实例化该类时所需的基本信息。如A.class返回的就是类A的Class对象。

    1 public class Test {
    2     public static void main(String [] args) throws ClassNotFoundException {
    3         Class clazz = Class.forName("Test");  // Class.forName()
    4         System.out.println(clazz.getName());
    5         System.out.println(Test.class.getName());  // 类名.class
    6         Test test = new Test();
    7         System.out.println(test.getClass().getName());  // 对象名.getClass()
    8     }
    9 }

    使用反射技术创建对象(Constructor类)

    1)通过Class类的newInstance()方法

    该方法要求该Class实例对象的对应类有无参构造方法。执行newInstance()实际就是实行类的无参构造方法来创建该类的实例对象。

    2)通过Constructor类的newInstance()方法

    首先使用Class对象获取指定的Constructor对象;然后调用Constructor对象的newInstance()方法创建Class对象对应类的实例对象。

    使用该方法可以选择使用指定的构造方法来创建实例对象。

    使用反射技术查询修改属性值(Field类)

    通过Class对象的getFields()方法返回Filed类型的数组,从而获得该类所包含的全部的Field属性

    通过Class对象的getField(String name)方法返回Field类型的实例对象,从而获得该类指定的Field属性

    每个Field实例对象对应一个属性,可以通过Field类提供的以下方法来访问或修改相应属性

    getXxx(Object obj)  // 获取obj对象该Field的属性值。此处的Xxx对应8种基本数据类型,如果该属性类型是引用类型则直接使用get(Object obj)

    setXxx(Object obj, Xxx val)  // 将obj对象的该Field赋值为val。此处的Xxx对应8种基本数据类型,如果该属性类型是引用类型则直接使用set(Object obj, Object val)

    setAccessible(Boolean flag)  // 若flag为true,则取消属性的访问权限控制,即使private属性也可以进行访问

    使用反射技术动态调用方法(Method类)

    通过Class对象的getMethods()方法返回Method类型的数组,从而获得该类所包含的全部的方法

    通过Class对象的getMethod(String name, Class<?>...parameterTypes)方法返回Method类型的实例对象,从而获得该类指定的方法

    每个Method对象对应一个方法,获得Method对象后,可以通过调用Method类的invoke()方法来调用对应的方法

    public Object invoke(Object obj, Object...args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException  // obj代表当前方法所属的对象的名字, args代表当前方法的参数列表,返回值Object是当前方法的返回值,即执行当前方法的结果。

  • 相关阅读:
    Nacos深入浅出(四)
    Nacos深入浅出(三)
    Nacos深入浅出(二)
    Nacos深入浅出(一)
    Mycat(1)
    redis事务
    git常用的方式
    redis主从复制
    redis持久化RDB和AOF
    Quartz
  • 原文地址:https://www.cnblogs.com/0820LL/p/9697490.html
Copyright © 2011-2022 走看看