java反射机制Reflection详解

yizhihongxing

Java反射机制Reflection详解

概述

Java反射机制是在运行时动态地获取一个类的信息以及针对这个类的对象操作的能力。通过反射,可以在运行时加载、探索和使用编译时已知的类。程序可以构造任意一个类的对象、获取该类中的字段、方法和构造方法、调用方法和访问/修改字段值。通过反射机制,可以在程序运行时动态地调用类的方法和字段,灵活性非常高。

获取Class对象

通过Java反射机制可以获取一个类的Class对象,而Class对象是用于获取该类的信息,如果要获取一个类的信息就需要先获得该类的Class对象。常见的方式是通过类名.class,例如:

Class<?> clazz = String.class;

还可以通过对象.getClass()方法来获取该对象对应类的Class对象,例如:

String str = "hello";
Class<?> clazz = str.getClass();

另外,还可以通过Class.forName()方法获取指定类的Class对象,例如:

Class<?> clazz = Class.forName("java.lang.String");

这种方式最常用于配置文件中指定类名字符串,然后运行时动态加载该类。

实例化对象

在获取到一个类的Class对象之后,就可以通过反射机制来实例化该类的对象了。这可以通过Class对象的newInstance()方法来实现,例如:

Class<?> clazz = String.class;
String str = (String)clazz.newInstance();

访问方法和成员变量

通过反射还可以访问类中的方法和成员变量(字段)。通过Class对象的getDeclaredMethod()方法可以获取该类中所有声明的方法,并通过Method对象来调用方法。例如:

Class<?> clazz = String.class;
Method method = clazz.getDeclaredMethod("substring", int.class, int.class);
String result = (String)method.invoke("hello world", 2, 6);
System.out.println(result); // 输出结果为 “llo w”

同样,可以通过Class对象的getDeclaredField()方法获取该类中的所有字段,并通过Field对象来访问并修改字段的值。例如:

Class<?> clazz = String.class;
Field field = clazz.getDeclaredField("value");
field.setAccessible(true); // 必须将该字段的可见性设置为true,否则会抛出IllegalAccessException异常
char[] value = (char[])field.get("hello");
value[1] = 'a';
System.out.println(new String(value)); // 输出结果为“hallo”

示例1:获取类中所有方法信息并调用指定方法

下面通过一个示例来演示如何利用Java反射机制来获取一个类中的所有方法,并调用指定方法。

我们定义一个Person类:

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

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void sayHello() {
        System.out.println("Hello, my name is " + name + ", I'm " + age + " years old.");
    }
}

然后使用反射机制来获取该类中的所有方法信息,并调用指定方法:

Class<?> clazz = Person.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    System.out.println(method.getName() + "()");
    if (method.getName().equals("sayHello")) {
        try {
            Person p = new Person("Tom", 20);
            method.invoke(p);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

<init>()
getName()
setName()
getAge()
setAge()
sayHello()
Hello, my name is Tom, I'm 20 years old.

该示例首先获取了Person类的Class对象,然后通过Class对象的getDeclaredMethods()方法获取该类中所有声明的方法,然后通过foreach循环遍历方法数组,并输出方法名称。在遍历过程中,如果方法名称等于“sayHello”,则实例化一个Person对象,并通过Method对象的invoke()方法来调用该方法。

示例2:通过反射机制修改数组的值

下面通过一个示例来演示如何使用反射机制来修改数组的值。

int[] array = {1, 2, 3, 4, 5};
Class<?> clazz = array.getClass();
if (clazz.isArray()) {
    int length = Array.getLength(array);
    for (int i = 0; i < length; i++) {
        System.out.print(Array.get(array, i) + " ");
        Array.set(array, i, i + 1);
    }
    System.out.println();
    for (int i = 0; i < length; i++) {
        System.out.print(Array.get(array, i) + " ");
    }
}

输出结果:

1 2 3 4 5 
1 2 3 4 5 

该示例首先定义了一个包含5个元素的int类型数组,然后获取该数组的Class对象,并判断该Class对象是否是数组类型。如果是数组类型,则通过Array类的静态方法get()和set()来获取和设置数组中的元素的值。在遍历数组的过程中,我们将每个元素的值都加1,并输出修改后的数组的值。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java反射机制Reflection详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • spring事务隔离级别、传播机制以及简单配置方式

    Spring事务管理 Spring提供了强大的事务管理服务,可以方便的实现事务控制,避免了在代码中写大量的底层JDBC事务代码。本篇文章将详细说明Spring事务的隔离级别、传播机制以及简单配置方式。 事务隔离级别 事务隔离级别是数据库保证数据一致性的重要手段,在并发访问数据库时可以防止不同线程对同一个数据产生相互影响的问题。Spring框架支持设置五个事务…

    Java 2023年5月20日
    00
  • 面向对象可视化工具:UML类图

    1. UML类图 UML(Unified Modeling Language,统一建模语言),用来描述软件模型和架构的图形化语言。 常用的UML工具软件有PowerDesinger、Rose和Enterprise Architect。 UML工具软件不仅可以绘制软件开发中所需的各种图表,还可以生成对应的源代码。 在软件开发中,使用UML类图可以更加直观地描述…

    Java 2023年4月27日
    00
  • SpringMVC+ZTree实现树形菜单权限配置的方法

    下面是完整攻略: 1. 准备工作 1.1 搭建SpringMVC项目 首先我们需要搭建一个SpringMVC项目,这里不做过多介绍,建议使用Maven进行管理。 1.2 引入ZTree插件 在搭建完SpringMVC项目后,在项目中引入ZTree插件。可以使用CDN的方式,也可以下载到本地引入。 1.3 数据库设计 在实现权限配置时,需要通过数据库保存树形菜…

    Java 2023年6月16日
    00
  • php UEditor百度编辑器安装与使用方法分享

    PHP UEditor百度编辑器安装与使用方法分享 什么是PHP UEditor百度编辑器? PHP UEditor百度编辑器是一个基于JavaScript的所见即所得富文本编辑器,能够在Web浏览器中编辑HTML文本和其他富媒体,如照片和视频。它是一个轻量级、高度定制的编辑器,非常适合PHP开发人员集成到他们的网站中。 安装PHP UEditor百度编辑器…

    Java 2023年6月15日
    00
  • Java加载资源文件时的路径问题的解决办法

    当我们需要在Java程序中读取资源文件时,经常会遇到路径问题。一般来说,Java中有三种方式可以读取资源文件: 使用绝对路径 使用相对路径 使用类路径 这里我们以读取配置文件为例,详细讲解以上三种方式的区别及解决办法。 1. 使用绝对路径 使用绝对路径是最简单的方式,直接指定文件的完整路径即可。但是这种方式会带来一些问题,因为在不同的机器上,文件的路径可能会…

    Java 2023年5月20日
    00
  • 如何实现 Java SpringBoot 自动验证入参数据的有效性

    Java SpringBoot 通过javax.validation.constraints下的注解,实现入参数据自动验证如果碰到 @NotEmpty 否则不生效,注意看下 @RequestBody 前面是否加上了@Valid Validation常用注解汇总 Constraint 详细信息 @Null 被注释的元素必须为 null @NotNull 被注释…

    Java 2023年4月18日
    00
  • 用intellij Idea加载eclipse的maven项目全流程(图文)

    以下是详细讲解“用IntelliJ Idea加载Eclipse的Maven项目全流程”的完整攻略。 步骤1:安装IntelliJ Idea 首先,需要在本地安装IntelliJ Idea,如果还没有安装,请官网下载并安装。 步骤2:打开IntelliJ Idea 安装完成后,打开IntelliJ Idea,点击菜单中的“Import Project” 步骤3…

    Java 2023年5月20日
    00
  • java使用命令行打包JAR

    下面是详细讲解Java使用命令行打包JAR的完整攻略: 一、JAR文件的概念 JAR(Java ARchive)文件是Java平台的标准打包文件,用于将多个类文件、资源文件以及META-INF目录打包为一个文件,方便程序的分发和部署。 二、使用命令行打包JAR的步骤 以下是使用命令行打包JAR的具体步骤: 创建一个目录,将需要打包的文件复制到该目录下。 打开…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部