【JavaSE】反射

1.、概述

Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法;对于给定的一个对象,都能够调用它的任意一个属性和方法。这种动态获取类的内容以及动态调用对象的方法称为反射机制。

Java的反射机制允许编程人员在对类未知的情况下,获取类相关信息的方式变得更加多样灵活,调用类中相应方法,是Java增加其灵活性与动态性的一种机制

  • 好处:
    1. 可以在程序运行过程中,操作这些对象。
    2. 可以解耦,提高程序的可扩展性。

2、功能

  • 在运行时判断任意的一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时获取泛型信息
  • 在运行时调用任意一个对象的成员变量和方法
  • 在运行时处理注解
  • 生成动态代理

优点:

可以实现动态创建对象和编译,体现出很大的灵活性

Public final Class getClass();

以上的方法返回值

获取Class对象的多种方式

//对象.getClass():getClass()方法在Object类中定义着。
//多用于对象的获取字节码的方式
person.getClass();

//Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
//多用于配置文件,将类名定义在配置文件中。读取文件,加载类
Class.forName();

//类名.class:通过类名的属性class获取
//多用于参数的传递
Student.class;

//只对包装类有效
Integer.Type;

//获得父类类型
Class.getSuperClass;

可以有反射对象的类型

  • 外部类
  • 接口
  • 数组
    • 在数组中,和长度无关,只要是一个维度并且类型相同,就是同一个class
  • 二维数组
  • 注解
  • 枚举类型
  • 基本数据类型
  • void
  • 反射对象本身

3.类的加载与ClassLoader的理解

类的主动引用(一定会发生类的初始化)

双亲委派机制

如果一个类加载器(ClassLoader)收到了类加载的请求,它首先不 会自己去尝试加载这个类,而是把这个请求委托给父类加载器去完成,每一个层次的类加载器都是如 此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完 成这个加载请求(它的搜索范围中没有找到所需要加载的类)时,子加载器才会尝试自己去加载。

通过反射获取运行时类的完整结构

  • Load:加载

    • 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构, 然后生成一个代表这个类的java.lang.Class对象.
  • Link:链接 :将Java类的二进制代码合并到JVM的运行状态之中的过程。

    • 验证:确保加载的类信息符合JVM规范,没有安全方面的问题
    • 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。
    • 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
  • Initialize:初始化

    • 初始化: 执行类构造器()方法的过程。类构造器()方法是由编译期自动收集类中所有类变量的赋值动作和静态 代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。

    当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。

    虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步:

3.反射的功能

3.1、Class对象功能:
获取运行时类的完整结构:
		1. 获取成员变量们
			 Field[] getFields() //获取所有public修饰的成员变量
			 Field getField(String name)   //获取指定名称的 public修饰的成员变量

			 Field[] getDeclaredFields()  //获取所有的成员变量,不考虑修饰符
			 Field getDeclaredField(String name)  
		2. 获取构造方法们
			 Constructor<?>[] getConstructors()  
			 Constructor<T> getConstructor(<?>... parameterTypes)  

			 Constructor<T> getDeclaredConstructor(<?>... parameterTypes)  
			 Constructor<?>[] getDeclaredConstructors()  
		3. 获取成员方法们:
			 Method[] getMethods()  
			 Method getMethod(String name,<?>... parameterTypes)  

			 Method[] getDeclaredMethods()  
			 Method getDeclaredMethod(String name,<?>... parameterTypes)  

		4. 获取全类名	
			String getName()  

例:

public class Demo2 {
    public static void main(String[] args) throws Exception {
        Class class1 = Class.forName("com.xupt.demo1.Student");

        Method[] methods = class1.getMethods();
        Method[] declaredMethods = class1.getDeclaredMethods();

        System.out.println(methods.length);
        System.out.println(declaredMethods.length);

        Field[] fields = class1.getFields();
        Field[] declaredFields = class1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);

        }
        Field name = class1.getDeclaredField("name");
        System.out.println(name);

        Constructor declaredConstructor = class1.getDeclaredConstructor();
        System.out.println(declaredConstructor.getName());
        ClassLoader classLoader = class1.getClassLoader();

        Constructor[] constructors = class1.getConstructors();
        Constructor[] declaredConstructors = class1.getDeclaredConstructors();

    }
}

Field:成员变量

操作:

设置值

void set(Object obj, Object value)

获取值

get(Object obj)

忽略访问权限修饰符的安全检查

setAccessible(true):

  • Method和Field、Constructor对象都有setAccessible()方法。
  • setAccessible作用是启动和禁用访问安全检查的开关。参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。
  • 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。
  • 使得原本无法访问的私有成员也可以访问
  • 参数值为false则指示反射的对象应该实施Java语言访问检查

Constructor:构造方法

创建对象:

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

Method:方法对象

  • 执行方法:
    • Object invoke(Object obj, Object… args)
  • 获取方法名称:
    • String getName:获取方法名
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值