百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

一篇文章搞懂 Java 反射_java反射是干嘛的

moboyou 2025-08-26 02:16 9 浏览

简述

Java 反射机制是指在程序运行状态中,对于任意一个类,都能获取其所有属性和方法;对于任意一个对象,都能调用其任意方法和属性。这种动态获取信息与动态调用对象方法的能力,就是 Java 反射机制的核心。

反射基础

  • RTTI(运行时类型识别) :区别于编译时已确定的类型,RTTI 能在运行时识别对象或类的信息,而反射是 RTTI 的重要实现方式。
  • 反射的本质:将类的属性、方法、构造器等组件 “解剖” 为一个个可操作的对象,从而实现动态操作类的能力。

Class 类

Java 中每个类或接口在 JVM 中都对应一个Class对象(包括基本数据类型和 void),它是反射的核心入口。

Class 类的特点

  • 是java.lang包下的 final 类,实现了多个接口。
  • 构造方法为private,仅由 JVM 创建和加载,开发者无法手动实例化。
  • 每个类在 JVM 中仅有一个对应的Class对象,全局唯一。
public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
    // 源码片段:构造方法私有
    private Class(ClassLoader loader) {
        classLoader = loader;
    }
}

类加载机制

  1. 编译:Java 文件编译为.class文件,包含类的完整信息。
  2. 加载:类加载器(ClassLoader)将.class文件加载到内存。
  3. 生成 Class 对象:JVM 为每个类创建唯一的Class对象,后续所有实例对象都基于该Class对象创建。

示意图逻辑
本地 / 网络的.class文件 → 类加载器 → 内存生成唯一Class对象 → 基于Class对象创建多个实例对象。

反射的核心类库

Java 反射主要依赖java.lang.Class类和java.lang.reflect包,其中关键类包括:

  • Constructor:类的构造方法
  • Field:类的成员变量
  • Method:类的成员方法
  • Modifier:访问修饰符工具类

常用方法速查表

方法

说明

forName(String)

通过全限定类名获取Class对象,立即加载并初始化类

getClass()

通过对象实例获取Class对象,返回实际类型

getName()

获取类的全限定名(含包名)

getSimpleName()

获取类名(不含包名)

isXXX()

判断类型(如isInterface()是否为接口,isEnum()是否为枚举)

getXXX()

获取单个成员(如getField(String)获取 public 字段),含父类 public 成员

getXXXs()

获取成员数组(如getMethods()获取所有 public 方法),含父类 public 成员

getDeclaredXXX()

获取本类声明的单个成员(含私有),不含父类

getDeclaredXXXs()

获取本类声明的所有成员(含私有),不含父类

newInstance()

通过无参构造器创建实例(需类有默认构造器)

获取 Class 对象的三种方式

  1. 类名.class:通过类名直接获取,编译时确定类型。
  2. 对象.getClass () :通过实例对象获取,运行时确定实际类型。
  3. Class.forName (全限定类名) :通过类路径动态获取,适用于未知类型。
// 示例
public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 方式1:类名.class
        Class<Student> clazz1 = Student.class;
        
        // 方式2:对象.getClass()
        Student student = new Student();
        Class<? extends Student> clazz2 = student.getClass();
        
        // 方式3:Class.forName()
        Class<?> clazz3 = Class.forName("com.example.Student");
    }
}

Constructor类用于获取和调用类的构造方法,支持访问私有构造器。

示例代码

public class Student {
    private String name;
    public int age;

    public Student() {}
    public Student(int age) { this.age = age; }
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 反射操作构造器
public class TestConstructor {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("com.example.Student");
        
        // 调用无参构造器
        Student s1 = (Student) clazz.newInstance();
        
        // 调用public单参构造器
        Constructor<?> c1 = clazz.getConstructor(int.class);
        Student s2 = (Student) c1.newInstance(18);
        
        // 调用私有构造器(需设置可访问)
        Constructor<?> c2 = clazz.getDeclaredConstructor(String.class, int.class);
        c2.setAccessible(true); // 解除私有访问限制
        Student s3 = (Student) c2.newInstance("Tom", 20);
    }
}

Field 类:操作成员变量

Field类用于获取和修改类的成员变量,包括私有变量。

示例代码

public class TestField {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Student.class;
        Student student = new Student();
        
        // 获取public字段(含父类)
        Field ageField = clazz.getField("age");
        ageField.set(student, 20); // 修改public字段
        System.out.println(ageField.get(student)); // 输出:20
        
        // 获取私有字段(仅本类)
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // 解除私有限制
        nameField.set(student, "Jerry");
        System.out.println(nameField.get(student)); // 输出:Jerry
    }
}

Method 类:操作成员方法

Method类用于获取和调用类的成员方法,包括私有方法。

示例代码

public class Student {
    private void showName() {
        System.out.println("Name: " + name);
    }
    public int getAge() {
        return age;
    }
}

// 反射操作方法
public class TestMethod {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Student.class;
        Student student = new Student();
        
        // 调用私有方法
        Method showMethod = clazz.getDeclaredMethod("showName");
        showMethod.setAccessible(true);
        showMethod.invoke(student); // 输出:Name: Jerry
        
        // 调用public方法
        Method getMethod = clazz.getMethod("getAge");
        int age = (int) getMethod.invoke(student);
        System.out.println("Age: " + age); // 输出:20
    }
}

反射的实际应用:Spring IOC

Spring 的 IOC 容器核心依赖反射实现:

  1. 扫描类路径下的@Component注解类,通过Class.forName()获取Class对象。
  2. 解析类的属性,若存在@Autowired注解,通过Field类设置属性可访问(setAccessible(true))。
  3. 自动注入依赖的 Bean 实例,实现 “控制反转”。

总结

反射是 Java 动态编程的核心技术,通过操作Class、Constructor、Field和Method等类,可在运行时灵活操作类的成员。尽管反射会牺牲部分性能并打破封装性,但在框架开发(如 Spring、MyBatis)中不可或缺。掌握反射,能更深入理解 Java 的底层机制和框架原理。

相关推荐

Excel技巧:SHEETSNA函数一键提取所有工作表名称批量生产目录

首先介绍一下此函数:SHEETSNAME函数用于获取工作表的名称,有三个可选参数。语法:=SHEETSNAME([参照区域],[结果方向],[工作表范围])(参照区域,可选。给出参照,只返回参照单元格...

Excel HOUR函数:“小时”提取器_excel+hour函数提取器怎么用

一、函数概述HOUR函数是Excel中用于提取时间值小时部分的日期时间函数,返回0(12:00AM)到23(11:00PM)之间的整数。该函数在时间数据分析、考勤统计、日程安排等场景中应用广泛。语...

Filter+Search信息管理不再难|多条件|模糊查找|Excel函数应用

原创版权所有介绍一个信息管理系统,要求可以实现:多条件、模糊查找,手动输入的内容能去空格。先看效果,如下图动画演示这样的一个效果要怎样实现呢?本文所用函数有Filter和Search。先用filter...

FILTER函数介绍及经典用法12:FILTER+切片器的应用

EXCEL函数技巧:FILTER经典用法12。FILTER+切片器制作筛选按钮。FILTER的函数的经典用法12是用FILTER的函数和切片器制作一个筛选按钮。像左边的原始数据,右边想要制作一...

office办公应用网站推荐_office办公软件大全

以下是针对Office办公应用(Word/Excel/PPT等)的免费学习网站推荐,涵盖官方教程、综合平台及垂直领域资源,适合不同学习需求:一、官方权威资源1.微软Office官方培训...

WPS/Excel职场办公最常用的60个函数大全(含卡片),效率翻倍!

办公最常用的60个函数大全:从入门到精通,效率翻倍!在职场中,WPS/Excel几乎是每个人都离不开的工具,而函数则是其灵魂。掌握常用的函数,不仅能大幅提升工作效率,还能让你在数据处理、报表分析、自动...

收藏|查找神器Xlookup全集|一篇就够|Excel函数|图解教程

原创版权所有全程图解,方便阅读,内容比较多,请先收藏!Xlookup是Vlookup的升级函数,解决了Vlookup的所有缺点,可以完全取代Vlookup,学完本文后你将可以应对所有的查找难题,内容...

批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数

批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数在电商运营、物流对账等工作中,经常需要统计快递“揽收到签收”的耗时——比如判断某快递公司是否符合“3天内送达”的服务承...

Excel函数公式教程(490个实例详解)

Excel函数公式教程(490个实例详解)管理层的财务人员为什么那么厉害?就是因为他们精通excel技能!财务人员在日常工作中,经常会用到Excel财务函数公式,比如财务报表分析、工资核算、库存管理等...

Excel(WPS表格)Tocol函数应用技巧案例解读,建议收藏备用!

工作中,经常需要从多个单元格区域中提取唯一值,如体育赛事报名信息中提取唯一的参赛者信息等,此时如果复制粘贴然后去重,效率就会很低。如果能合理利用Tocol函数,将会极大地提高工作效率。一、功能及语法结...

Excel中的SCAN函数公式,把计算过程理清,你就会了

Excel新版本里面,除了出现非常好用的xlookup,Filter公式之外,还更新一批自定义函数,可以像写代码一样写公式其中SCAN函数公式,也非常强大,它是一个循环函数,今天来了解这个函数公式的计...

Excel(WPS表格)中多列去重就用Tocol+Unique组合函数,简单高效

在数据的分析和处理中,“去重”一直是绕不开的话题,如果单列去重,可以使用Unique函数完成,如果多列去重,如下图:从数据信息中可以看到,每位参赛者参加了多项运动,如果想知道去重后的参赛者有多少人,该...

Excel(WPS表格)函数Groupby,聚合统计,快速提高效率!

在前期的内容中,我们讲了很多的统计函数,如Sum系列、Average系列、Count系列、Rank系列等等……但如果用一个函数实现类似数据透视表的功能,就必须用Groupby函数,按指定字段进行聚合汇...

Excel新版本,IFS函数公式,太强大了!

我们举一个工作实例,现在需要计算业务员的奖励数据,右边是公司的奖励标准:在新版本的函数公式出来之前,我们需要使用IF函数公式来解决1、IF函数公式IF函数公式由三个参数组成,IF(判断条件,对的时候返...

Excel不用函数公式数据透视表,1秒完成多列项目汇总统计

如何将这里的多组数据进行汇总统计?每组数据当中一列是不同菜品,另一列就是该菜品的销售数量。如何进行汇总统计得到所有的菜品销售数量的求和、技术、平均、最大、最小值等数据?不用函数公式和数据透视表,一秒就...