java-反射

Java反射机制允许程序在运行时获取类的内部信息并进行操作,如成员变量、构造器和方法。它涉及Class、Method、Field和Constructor等类,用于动态创建对象、访问成员以及生成动态代理。反射虽带来灵活性,但会降低执行效率。类加载分为静态和动态,通过Class.forName()或对象的getClass()方法获取Class对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 程序在计算机有三个阶段:

 

一、反射机制

1. Java Reflection

① 反射机制允许程序在执行期借助于

  Reflection API 取得任何类的内部信息

  (比如成员变量,构造器,成员方法等),

  并能操作对象的属性及方法。[反射在

  设计模式框架底层都会用到]

② 加载完类之后,在堆中就产生了一个

  Class 类型的对象(一个类只有一个Class

  对象),这个对象包含了类的完整结构信

  息,通过这个对象得到类的结构,所以,

  形象的称之为:反射

  p 对象 ---> 类型 Person 类

  Class 对象 cls ---> 类型 Class类

2. Java 反射机制可以完成

① 在运行时判断任意一个对象所属的类

② 在运行时构造任意一个类的对象

③ 在运行时得到任意一个类所具有的成员

    变量方法

④ 在运行时调用任意一个对象的成员变量

    和方法

⑤ 生成动态代理 

3. 反射相关的主要类

java.lang.Class:代表一个类,Class 对象

    表示某个类加载后在堆中的对象 

java.lang.reflect.Method:代表类的方法,

    Method 对象表示某个类的方法

java.lang.reflect.Field:代表类的成员变量,

    Field 对象表示某个类的成员变量

java.lang.reflect.Constructor:代表类的构

    造方法,Constructior 对象表示构造器

这些类在 java.lang.reflection

 

4. 反射优点和缺点

① 优点:可以动态的创建和使用对象(也是框

    架底层核心),使用灵活,没有反射机制,

    框架技术就失去底层支撑

② 缺点:使用反射级别是解释执行,对执行

    速度有影响

5. 反射调用优化-关闭访问检查

MethodField、Constructor 对象都有

    setAccessible() 方法

 setAccessible 作用是启动和禁用访问安全

    检查的开关 

③ 参数值为 true 表示反射的对象在使用时

    消访问检查,提高反射的效率

    参数值为 false 则表示反射的对象执行访问

    检查

二、Class 类

① Class 也是类,因此也继承 Object 类

② Class 类对象不是 new 出来的,而是系统

    创建

③ 对于某个类的 Class 类对象,在内存中只有

    一份,因为类只加载一次

④ 每个类的实例都会记得自己是由哪个 Class

    实例所生成

⑤ 通过 Class 对象可以完整地得到一个类的完

    整结构,通过一系列 API

⑥ Class 对象是存放在堆的

⑦ 类的字节码二进制数据,是放在方法区的,

    有的地方称为类的元数据(包括 方法代码,变

    量名,方法名,访问权限等等)

2. Class 类的常用方法


    //1 . 获取到 Car 类 对应的 Class 对象
    //<?> 表示不确定的 Java 类型
    Class<?> cls = Class.forName(classAllPath);

    //2. 输出 cls
    System.out.println(cls); //显示 cls 对象, 是哪个类的 Class 对象
    System.out.println(cls.getClass());//输出 cls 运行类型 java.lang.Class

    //3. 得到包名
    System.out.println(cls.getPackage().getName());//包名

    //4. 得到全类名
    System.out.println(cls.getName());

    //5. 通过 cls 创建对象实例
    Car car = (Car) cls.newInstance();
    System.out.println(car);//car.toString()

    //6. 通过反射获取属性 brand
    Field brand = cls.getField("brand");
    System.out.println(brand.get(car));//宝马

    //7. 通过反射给属性赋值
    brand.set(car, "奔驰");
    System.out.println(brand.get(car));//奔驰

    //8 我希望大家可以得到所有的属性(字段)
    System.out.println("=======所有的字段属性====");
    Field[] fields = cls.getFields();
    for (Field f : fields) {
    System.out.println(f.getName());//名称

3. 获取 Class 类对象

① 前提:

    已知一个类的全类名,且该类在类路径下,可

    通过 Class 类的静态方法 forName() 获取,可

    能抛出 ClassNotFoundException

    实例:

    Class cls1 = Class.forName("java.lang.Cat"); 

    应用场景:

    多用于配置文件,读取类全路径,加载类

② 前提:

    若已知具体的类,通过类的 class 获取,该方

    式最为安全可靠,程序性能最高

    实例:

    Class cls2 = Cat.class;

    应用场景:

    多用于参数传递,比如通过反射得

    到对应构造器对象   

③ 前提:

    已知某个类的实例,调用该实例的 getClass()

    方法获取 Class 对象

    实例:

    Class clazz = 对象.getClass();//运行类型

    应用场景:

    通过创建好的对象,获取 Class 对象

④ 其他方式

   ClassLoader cl = 对象.getClass().getClassLoader();

   Class clazz4 = cl.loadClass("类的全类名");

⑤ 基本数据(int,char,boolean,float,double,

     byte,long,short

    按如下方式得到 Class 类对象:

     Class cls = 基本数据类型.class 

⑥ 基本数据类型对应的包装类,可以通过.TYPE 得到

    Class 类对象

    Class cls = 包装类.TYPE

 4.哪些类型有Class 对象

三、类加载

反射机制是 Java 实现动态语言的关键,也就是

通过反射实现类动态加载

静态加载:编译时加载相关的类,如果没有则

   报错,依赖性太强

动态加载:运行时加载需要的类,如果运行时

   不用该类,即使不存在该类,则不报错,降低了

   依赖性

2.类加载时机

 当创建对象时(new) //静态加载

② 当子类被加载时,父类也加载 //静态加载

③ 调用类中的静态成员时 //静态加载

④ 通过反射 //动态加载

Class.forName("com.test.Cat");

3.类加载过程图

4.类加载各阶段完成任务

5.加载阶段

6. 连接阶段--验证

7. 连接阶段--准备

  

8. 连接阶段--解析

  虚拟机将常量池内的符号引用替换为直接引用的过程

9. 初始化 (Initialization)

四、反射获取类的结构信息

  java.lang.Class

  java.lang.reflect.Field

  java.lang.reflect.Method

  java.lang.reflect.Constructor

五、通过反射创建对象

六、通过反射访问类中的成员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值