4.3 Java之反射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lwz45698752/article/details/82849696


反射初探

在这里插入图片描述

  • 反射机制

    • 编译时不指定类型,运行时动态获取类型从而进行相应操作(动态性)
    • 通过反射动态创建对象
  • 一段通用性代码(模板)然后对应数据库,每一条数据看作类的对象

  • 代码作用:获取数据库连接 返回一条数据对应的一个对象(相当于在程序中对应一个customer类)

  • 根据传入参数,动态创建对应类的对象

  • 编译时到字节码文件中,运行时把字节码文件对应的类加载到内存里(运行时加载,即运行时类) --------解释运行时类的由来

  • 运行时类的字节码文件对应的类充当Class的实例

  • 任何一个类对于反射的Class对象来说是完全暴露的

  • clazz为栈空间的引用,堆空间实体为Person类本身,从而将该类各结构完全暴露

  • 调用属性操作

    • 首先通过反射获取对应person类的结构信息(如属性)
    • f1是name属性引用
    • 关注当属性私有公有时不同的调用方法(name共有,age私有)
  • getMethod方法的形参为Class类型,又考虑到display的形参为字符串,所以传入字符串类型的class

Class类

在这里插入图片描述
在这里插入图片描述

  • 返回类对象对应的运行时类(类型为Class)
  • 每个类对应一个class文件
  • 运行时加载到缓存区(非过河拆桥)
  • 只加载一次,所以Class类实例称为获取而不是创建(创建是可多次的,获取只创建一次)
    怼到类本身位置上

编译异常要处理

创建Class类对象方法(四种)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • getName为获取类的路径(如className所示)

类的加载器

在这里插入图片描述

  • 共三种类加载器
  • 关注这三种类加载器对应的类

在这里插入图片描述

  • 字节码文件通过命令解释运行
  • 首先装载起来,然后校验和解释
  • 加载器:将字节码文件对应结构加载到内存中

类的加载过程

在这里插入图片描述

  • 类的加载包含三步:如上图
  • 类的初始化具体指对静态属性和方法初始化

实例

在这里插入图片描述

在这里插入图片描述

  • 由运行结果知,初始为系统类加载器,获取父类,得扩展类加载器,获取父类,应该得引导类加载器,但该加载器不能获取,返回null

  • 系统类加载器负责自定义的类

  • 无法获取引导类加载器(核心类库加载自动完成),试图获取则返回null

  • 获取加载器的作用在于显式加载某个类
    在这里插入图片描述

  • 加载文件的两种方式

  • 法一是获取当前包下创建的文件

  • 法二是在在当前文件目录下以流的形式获取一个文件,即在工程下创建

  • 在这里插入图片描述
    在这里插入图片描述

创建运行时类的对象

在这里插入图片描述

  • “==”判断是否指向同一个地址
  • 返回皆为true,说明每个类只加载了一次

在这里插入图片描述

  • Class对象对应加载到内存中的一个类
  • 加载到内存中,则创建了对应的Class对象(以后一直在缓存中,供调用)
  • 不管直接创建还是通过反射,都是调用类结构中的构造器
  • 要求类保留空参构造器,注意权限问题

获取类的结构

获取类属性

在这里插入图片描述

在这里插入图片描述

  • 父类包括间接父类
  • 一个是只能获取父类及其本身public属性,一个是本类的所有属性

在这里插入图片描述

在这里插入图片描述

  • 不同修饰符对应不同int值(返回值类型为int),通过toString方法转化
  • default权限对应的字符串为空(int id前空缺)

获取类方法

在这里插入图片描述

在这里插入图片描述

  • 关注点类比类属性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 父类指直接父类及其间接父类
  • 方法的异常修饰指的是throws,try/catch块不可见
  • 异常和参数获取都是数组返回

获取构造器

  • 进一步获取构造器结构类比方法

获取父类及带泛型的父类

在这里插入图片描述

  • 获取父类采用第一种方法是不带泛型的

获取父类泛型(重点)

在这里插入图片描述

  • type是个接口,Class实现该接口,所以可以向下转型
  • 首先获取带泛型的父类,然后将其强转为子接口,调用该子接口获取泛型的方法,最后强转为Class获取其泛型名

获取实现的接口和所在包

在这里插入图片描述

  • 获取的接口不包括父接口,只是自身类实现的接口

获取注解

在这里插入图片描述

  • 只有声明为Runtime的注解才能被反射获取

反射调用类对象的属性

在这里插入图片描述

  • 关注权限修饰符对反射调用类对象属性的影响(declared得到的属性要特别考虑权限问题)

反射调用方法

在这里插入图片描述

  • 只能获取声明为public方法
  • invoke方法返回值即实际调用的方法返回值

反射调用构造器

在这里插入图片描述

  • 关注int.class(参数为int类型,同时要求传入Class类型参数)
  • declared和setAccessible配套使用

猜你喜欢

转载自blog.csdn.net/lwz45698752/article/details/82849696
4.3