Java Reflect反射 笔记+作业

本文详细介绍了Java的反射机制,包括类加载的过程、类加载器的分类与双亲委派模型,以及类加载的六大时机。讲解了如何通过反射获取字节码文件对象、构造方法、成员变量和方法,并探讨了反射在配置文件处理、Junit测试中的应用和自定义类加载器的实现。此外,还分享了反射在实际项目中的应用案例。
摘要由CSDN通过智能技术生成

此笔记根据老师上课内容整理,并非本人100%原创

类加载

之前学的

过程

  • 加载

    • 通过类加载器(ClassLoader)加载class文件,加载到内存

    • 在这个过程当中,会在内存中生成一个对象,这个类所对应的字节码文件对象(java.lang.Class)

  • 链接

    • 验证 : 对字节码文件正确性的校验(cafe babe 咖啡宝贝)

    • 准备: 为类的静态成员分配内存, 并赋予默认初值

      •  static int a = 10

    • 解析: 把符号引用(用一组符号来描述被引用的目标)替换为直接引用(真实的内存地址)

  • 初始化

    • 执行静态代码块的内容,给静态成员赋真实的值

类加载器

分类

  1. Bootstrap ClassLoader 根类加载器 负责Java运行时核心类的加载,JDK中JRE的lib目录下rt.jar
  2. Extension ClassLoader 扩展类加载器 负责JRE的扩展目录中jar包的加载,在JDK中JRE的lib目录下ext目录
  3. Sysetm(App) ClassLoader 系统类加载器/应用加载器 负责加载自己定义的Java类

 package _23reflect.com.cskaoyan._01introduction;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 14:45
  **/
 ​
 public class Demo {
     public static void main(String[] args) {
         // 获取系统类加载器
         ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
         System.out.println(systemClassLoader);
 ​
         // 获取扩展类加载器
         ClassLoader parent = systemClassLoader.getParent();
         System.out.println(parent);
 ​
         // 获取根类加载器 为什么是null? 根类加载器不是java写的
         ClassLoader parent1 = parent.getParent();
         System.out.println(parent1);
 ​
         // 查看系统类加载器的加载路径
         System.out.println(System.getProperty("java.class.path").
                 replace(";", System.lineSeparator()));
 ​
         // 查看扩展类加载器的加载路径
         System.out.println("--------------");
         System.out.println(System.getProperty("java.ext.dirs").
                 replace(";", System.lineSeparator()));

     }
 }
 

双亲委派模型

类加载的6大时机

  1. 创建类的实例(首次创建该类对象)

  2. 访问类的静态变量(首次)

  3. 调用类的静态方法(首次)

  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

  5. 加载某个类的子类,会先触发父类的加载

  6. 直接使用java.exe命令来运行某个主类,也就是执行了某个类的main()方法

java代码的3个阶段

反射

什么是反射

获取运行时类信息的一种手段

反射技术的起点就是获取字节码文件对象

获取字节码文件对象的几种方式

  • 对象.getClass()

  • 类/接口名.class

  • Class.forName(String className) 全限定名

  • ClassLoader.loadClass(String name)

package _23reflect.com.cskaoyan._02cls;
 ​
 /**
  * @description: 获取字节码文件对象
  * @author: 景天
  * @date: 2022/7/1 15:54
  **/
 ​
 public class Demo {
     public static void main(String[] args) throws ClassNotFoundException {
         // - 对象.getClass()
         Stu stu = new Stu();
         Class<? extends Stu> c1 = stu.getClass();
         //- 类名.class
         Class<Stu> c2 = Stu.class;
 ​
         System.out.println(c1 == c2);
 ​
         //- Class.forName(String className)  全限定名
         Class<?> c3 = Class.forName("_23reflect.com.cskaoyan._02cls.Stu");
         System.out.println(c1 == c3);
         //- ClassLoader.loadClass(String name)
         ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
         Class<?> c4 = systemClassLoader.loadClass("_23reflect.com.cskaoyan._02cls.Stu");
 ​
         System.out.println(c1 == c4);
     }
 }
 ​
 class Stu{}

注意:

  • 无论是哪种方式获取的字节码文件对象,都是同一个

package _23reflect.com.cskaoyan._02cls;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 16:00
  **/
 ​
 public class Demo2 {
     public static void main(String[] args) throws ClassNotFoundException {
         // 类名.class
         //Class<A> c1 = A.class;
 ​
         // Class.forName(String name)
         Class<?> c2 = Class.forName("_23reflect.com.cskaoyan._02cls.A");
     }
 }
 ​
 class A{
     static {
         System.out.println("static");
     }
 }

关于Class

Class 类的实例表示正在运行的 Java 应用程序中的类和接口

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的

配置文件(.properties)

.properties .yml .xml 配置文件

一般放的都是配置信息 数据库配置信息 第三方服务的信息

开发环境 测试环境 线上环境

Properties

Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

构造方法

Properties() 创建一个无默认值的空属性列表。

成员方法

void load(InputStream inStream) 从输入流中读取属性列表(键和元素对)。
void load(Reader reader) 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
String getProperty(String key) 用指定的键在此属性列表中搜索属性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值