10分钟带你理解Java中的反射

10分钟带你理解Java中的反射

什么是反射?

先从字面意思来理解,反射(Reflection)就是“映射回去”的意思。在Java中,反射就是运行时动态地获取一个类的信息,并可以对其进行操作的能力。

反射机制在运行时确定一个类的方法、字段等信息,而不需要在编译时确定。这样就可以在运行时通过一个字符串来获取相应的类、方法、属性等,增加了代码的灵活性。

反射基础

Java反射主要通过以下三个类来实现:

  • Class:表示一个类或接口,在运行时可以动态获取和操作它的信息;
  • Method:表示类的方法;
  • Field:表示类的属性。

获取Class对象

在Java中,Class类是用来描述类信息的,每个类在虚拟机中都有一个对应的Class对象,我们可以通过以下三种方式来获取Class对象:

  1. 调用对象的getClass()方法;
  2. 调用类的静态变量class;
  3. 使用Class.forName()方法。
//获取Object类的Class对象
Class<Object> clazz1 = new Object().getClass();
Class<Object> clazz2 = Object.class;
Class<?> clazz3 = Class.forName("java.lang.Object");

获取类的信息

通过Class对象我们可以获取一个类的字段、方法、构造方法等信息。

//获取类的所有字段
Field[] fields = clazz.getFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

//获取类的所有方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
    System.out.println(method.getName());
}

//获取类的所有构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
    System.out.println(constructor.getName());
}

调用方法/属性

通过反射我们可以在运行时调用类的方法和属性。下面是一个示例,通过反射获取一个类的字段并设置其值:

public class MyClass {
    private int x;
    public MyClass(){
        this.x = 10;
    }
    public void print(){
        System.out.println(this.x);
    }
}

//获取MyClass类的对象
Class<MyClass> clazz = MyClass.class;
MyClass obj = clazz.newInstance();

//获取MyClass类的x属性
Field field = clazz.getDeclaredField("x");

//设置x属性的值
field.setAccessible(true);
field.set(obj, 20);

//调用print方法输出x的值
Method method = clazz.getMethod("print");
method.invoke(obj);

示例说明

示例一

假设我们在开发一个配置文件读取工具时需要对配置文件进行一个解析,但是具体的配置文件格式未知,为了解析不同的配置文件,我们可以通过反射来动态获取对象的属性。

public class AppConfig {
    private String name;
    private String version;
    //getters and setters
}

public class ConfigParser {
    public static AppConfig parse(String fileName){
        File configFile = new File(fileName);
        Properties props = new Properties();
        try {
            props.load(new FileInputStream(configFile));
            //通过反射来动态获取对象的属性
            AppConfig config = new AppConfig();
            Class clazz = AppConfig.class;
            Field[] fields = clazz.getDeclaredFields();
            for(Field field : fields){
                String name = field.getName();
                String value = props.getProperty(name);
                if(value != null){
                    field.setAccessible(true);
                    field.set(config, value);
                }
            }
            return config;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

示例二

在某些情况下,我们可能需要根据类的名称动态创建对象并调用其方法。

public class MessageService {
    public void sendMessage(String message){
        System.out.println("send message: " + message);
    }
}

public class MessageServiceFactory {
    public static Object create(String className){
        try {
            Class clazz = Class.forName(className);
            return clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

public class MessageClient {
    public static void main(String[] args) {
        String className = "demo.MessageService";
        Object obj = MessageServiceFactory.create(className);
        if(obj instanceof MessageService){
            MessageService messageService = (MessageService) obj;
            messageService.sendMessage("Hello World!");
        }
    }
}

总结

反射机制是Java强大的一个特性,可以让我们在运行时获取类的信息,并对其进行动态操作。但是反射也带来了额外的开销和泛滥使用的风险,因此在使用反射时需要小心谨慎。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:10分钟带你理解Java中的反射 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • passwd总结

    以下是关于“passwd总结”的完整攻略,包括定义、使用方法、示例说明和注意事项。 定义 passwd是一个Linux/Unix系统中的命令,用于更改用户的密码。它可以让用户更改自己的密码,也可以让管理员更改其他用户的密码。 使用方法 使用passwd命令更改密码的方法如下: 更改自己的密码 如果要更改自己的密码,可以在终端或命令行窗口中输入以下命令: ba…

    other 2023年5月8日
    00
  • linux轻量级 Web 服务器第1/2页

    Linux轻量级Web服务器攻略 本攻略旨在为初学者提供Linux轻量级Web服务器的基本操作和安装方法。在本攻略中,我们将会涉及以下主题: 轻量级Web服务器的定义和作用 安装和配置Apache 理解Apache的常见配置文件 使用Apache来部署简单的网站 检测Apache的服务状态和日志 1. 轻量级Web服务器的定义和作用 什么是轻量级Web服务器…

    other 2023年6月27日
    00
  • C语言全面细致精讲操作符的使用

    C语言全面细致精讲操作符的使用 操作符的基本介绍 在C语言中有非常多的操作符,用于实现变量之间的相互赋值、比较、计算等操作。操作符是C语言中非常重要的一部分,并且涉及到了C语言的基础知识。操作符可以分为以下几类: 算数操作符 关系操作符 逻辑操作符 位操作符 赋值操作符 其他操作符 其中,算数操作符用于执行基本的算术运算,比如加、减、乘、除等;关系操作符用于…

    other 2023年6月27日
    00
  • mysql去重的方法整理

    以下是“MySQL去重的方法整理”的完整攻略: 1. 去重的概念 在MySQL中,去重是指从查询结果中删除重复的行。当查询结果包含多个相同的行时,去重可以帮助我们只显示一次这些行,从而使查询结果更加简洁和易读。 2. MySQL去重的方法 MySQL提供了多种去重的方法,包括使用DISTINCT关键字、GROUP BY子句和HAVING子句等。下面分别介绍这…

    other 2023年5月8日
    00
  • SQLSERVER2005 中树形数据的递归查询

    SQLServer 2005提供了递归查询(Recursive Query)功能,可以用来查询树形数据。常用的场景是查询组织机构、产品分类、地区等具有层级关系的数据。 递归查询的语法如下: WITH CTE AS ( — Anchor member SELECT … UNION ALL — Recursive member SELECT … FR…

    other 2023年6月27日
    00
  • Bootstrap实现带暂停功能的轮播组件(推荐)

    下面是关于“Bootstrap实现带暂停功能的轮播组件(推荐)”的完整攻略: 标准Bootstrap轮播组件 首先,我们先来了解一下标准的Bootstrap轮播组件。Bootstrap是一个流行的前端框架,几乎所有的网站前端开发都会用到。Bootstrap提供了很方便的轮播组件,可以在网站中实现图片轮播、新闻轮播等功能。 HTML代码 需要引入Bootstr…

    other 2023年6月20日
    00
  • 神经网络优化器

    以下是关于“神经网络优化器”的完整攻略,包含两个示例说明。 什么是神经网络优化器 神经网络优化器是一种用于训练神经网络的算法,它可以自动调整神经网络中的权重和偏差以最化损失函数。优化器的目标是找到最优的权重和偏差,以使神经网络的输出与实际输出尽可能接近。 常见的神经网络优化器 以下是一些常见的神经网络优化器: 1. 随机梯度下降(SGD) 随机梯度下降是一种…

    other 2023年5月9日
    00
  • grafana下载与安装(v5.4.1)

    Grafana下载与安装(v5.4.1) Grafana是一款流行的开源数据可视化工具,它可以将各种数据源转换为漂亮的图表。本文将演示如何在Linux系统中下载安装Grafana(版本为v5.4.1)。 步骤一:下载Grafana安装包 在Grafana的官方网站 https://grafana.com/grafana/download 中,我们可以找到Gr…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部