Java--反射机制原理、几种Class获取方式及应用场景

学习Java的小伙伴,可能听过,但是熟悉又有点陌生,本文主要是通过思考面试中经常被问到的几个的问题,再通过结合及进行讲解,加深自己对的认知和理解,也希望能帮助到有需要的小伙伴~(1)Java反射机制()是Java语言中一种的能力,主要作用是~更简单点的说就是Java程序在运行时(动态)通过创建一个类的反射对象,再对类进行相关操作,比如:(2)一般情况下,我们使用某个类,都会知道这个类,以及要用它来做什么,可以直接通过实例化创建对象,然后使用这个对象对类进行操作,这个就属于~(3)而则是一开始并不知道要初
摘要由CSDN通过智能技术生成

目录

??学习背景

学习Java的小伙伴,可能听过Java反射机制,但是熟悉又有点陌生,本文主要是通过思考面试中经常被问到的几个Java反射机制的问题,再通过理论知识结合代码实例应用场景进行讲解,加深自己对Java反射机制的认知和理解,也希望能帮助到有需要的小伙伴~
在这里插入图片描述

??一、Java反射机制是什么?

??1.1 反射原理

(1)Java反射机制(Java Reflection)是Java语言中一种动态(运行时)访问、检测 & 修改它本身的能力,主要作用是动态(运行时)获取类的完整结构信息 & 调用对象的方法~
更简单点的说就是Java程序在运行时(动态)通过创建一个类的反射对象,再对类进行相关操作,比如:

  • 获取该对象的成员变量 & 赋值
  • 调用该对象的方法(含构造方法,有参/无参)
  • 判断该对象所属的类

PS:不过说实话,直接看比较官方的定义还是有点难理解,再来更加通俗点的说吧~

(2)一般情况下,我们使用某个类,都会知道这个类,以及要用它来做什么,可以直接通过new实例化创建对象,然后使用这个对象对类进行操作,这个就属于正射~

(3)而反射则是一开始并不知道要初始化的是什么类,无法使用new来实例化创建对象,主要是通过JDK提供的反射API来实现,在运行时才知道要操作的是什么类,并且可以获取到类的完整构造以及调用对应的方法,这就是反射~

??1.2 反射例子

代码如下:

package com.justin.java.lang;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * @program: Jdk1.8 Test
 * @description: 正射、反射简单调用示例
 * @author: JustinQin
 * @create: 2021/8/22 13:23
 * @version: v1.0.0
 **/
public class Student {
    private int id;

    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }

    public static void main(String[] args) throws Exception{
        //一、正射调用过程
        Student student = new Student();
        student.setId(1);
        System.out.println("正射调用过程Student id:" + student.getId());

        //二、反射调用过程
        Class clz = Class.forName("com.justin.java.lang.Student");
        Constructor studentConstructor = clz.getConstructor();
        Object studentObj = studentConstructor.newInstance();
        
        Method setIdMethod = clz.getMethod("setId", int.class);
        setIdMethod.invoke(studentObj, 2);
        Method getIdMethod = clz.getMethod("getId");
        System.out.println("正射调用过程Student id:" + getIdMethod.invoke(studentObj));
    }
}

输出结果:

正射调用过程Student id:1
反射调用过程Student id:2

上述例子反射的调用过程,可以看到获取一个类的反射对象,主要过程为:

  • 获取类的Class实例对象
  • 根据Class实例对象获取Constructor对象
  • 再根据Constructor对象的newInstance方法获取到类的反射对象

获取到类的反射对象后,就可以对类进行操作了~ 例如,上述示例中对类的方法进行调用过程为:

  • 根据Class实例对象获取到类的Method对象
  • 再根据Method对象的invoke方法调用到具体类的方法

前面一点也提到了获取到类的Class实例对象,上面示例反向调用过程中我们是通过Class.forName("类的全局定名")这种方式来获取到类的Class实例对象,除了这种,常用的还有其他两种,往下讲解~

??二、Java反射机制中获取Class的三种方式及区别?

在这里插入图片描述

??2.1 Class的几种获取方式

(1)获取类的java.lang.Class实例对象,常见的三种方式分别为:

  • 通过MyClass.class获取,这里的MyClass指具体类~~
  • 通过Class.forName("类的全局定名")获取,全局定名为包名+类名
  • 通过new MyClass().getClass()获取,这里的MyClass指具体类~

(2)通过MyClass.class获取,JVM会使用ClassLoader类加载器将类加载到内存中,但并不会做任何类的初始化工作,返回java.lang.Class对象

(3)通过Class.forName("类的全局定名")获取,同样,类会被JVM加载到内存中,并且会进行类的静态初始化工作,返回java.lang.Class对象

(4)通过new MyClass().getClass()获取,这种方式使用了new进行实例化操作,因此静态初始化和非静态初始化工作都会进行,getClass方法属于顶级Object类中的方法,任何子类对象都可以调用,哪个子类调用,就返回那个子类的java.lang.Class对象

PS: 这3种方式,最终在JVM堆区对应类的java.lang.Class对象都属于同一个,也就是内存地址相同,进行==双等号比较结果为true,原因是JVM类加载过程中使用的是同一个ClassLoader类加载器加载某个类,不论加载多少次,生成到堆区的java.lang.Class对象始终只有一个,除非自定义类加载器,破坏JVM的双亲委派机制,使得同一个类被不同类加载器加载,JVM才会把它当做两个不同的java.lang.Class对象

??2.2 代码演示几种方式的区别

创建一个实体类,分别在实体类中创建类的静态代码块动态代码块有参构造方法无参构造方法,方便测试几种方式的区别及内存地址是否相同~

(1)实体类:

public class MyClass {
    private static final String staticStr = "Hi";
    private static i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值