java反射机制Reflection详解

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日

相关文章

  • SpringBoot2.X Kotlin系列之数据校验和异常处理详解

    SpringBoot2.X Kotlin系列之数据校验和异常处理详解 概述 本文主要介绍在使用SpringBoot2.x和Kotlin进行Web开发时,如何实现数据校验和异常处理。我们将会使用@Valid注解进行数据校验,并使用ExceptionHandler来捕获异常并统一处理。 数据校验 SpringBoot2.x 数据校验注解 SpringBoot2.…

    Java 2023年5月19日
    00
  • 一文搞定接口幂等性架构设计方案

    幂等性介绍 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中,就会存在若干个微服务,而且服务间也会产生相互通信调用。那么既然产生了服务调用,就必然会存在服务调用延迟或失败的问题。当出现这种问题,服务端会进行重试等操作或客户端有可能会进行多次点击提交。如果这样请求多次的话,那最终处理的数据结果就一定要保证统一,如支付场景。此时就…

    Java 2023年4月22日
    00
  • Java多线程之显示锁和内置锁总结详解

    Java多线程之显示锁和内置锁总结详解 前言 随着现代计算机的发展,CPU的速度和核心数量逐渐增加,让多线程编程变得越来越重要。Java作为一门支持多线程的语言,在多线程编程方面也提供了一系列的API和机制。本文将重点介绍Java中的两种锁:显示锁和内置锁,并对它们进行详细分析和对比。 什么是锁? 在多线程编程中,为了保证共享资源的正确访问,我们经常需要对这…

    Java 2023年5月19日
    00
  • SpringData @Query和@Modifying注解原理解析

    当使用Spring Data JPA进行数据库操作时,我们可能需要对一些自定义查询进行优化。Spring Data提供了@Query和@Modifying注解来支持这种自定义查询操作。 @Query注解 @Query注解可以被使用在repository接口的方法上,它可以用于定义一个自定义的查询语句。 Spring Data JPA将@Query注解和方法的…

    Java 2023年5月20日
    00
  • Java中Arrays的介绍及使用方法示例

    Java中Arrays的介绍及使用方法示例 1. 什么是Arrays 在Java编程语言中,Arrays是一个类,用来操作数组的工具类,包含了一些静态方法,如排序和二分查找等。 2. Arrays的常用方法 2.1 初始化数组 Arrays类提供的最常用的初始化数组的方法是:Arrays.fill(),可以用来填充一个数组。 // 初始化长度为10的数组,全…

    Java 2023年5月26日
    00
  • 一个简单的java学生寝室查询系统

    一个简单的Java学生寝室查询系统 简介 这是一个用Java编写的学生寝室查询系统,可供学生、宿管等人查询学生所在的寝室。系统通过读取Excel文件中的数据,进行查询和输出信息。 功能 根据学生的姓名或学号查询寝室号 根据寝室号查询寝室内的所有学生信息 输出全部学生信息 实现步骤 步骤1:确定功能需求 首先需要确定此系统需要实现的功能,包括查询和输出信息。通…

    Java 2023年5月31日
    00
  • Java C++刷题leetcode1106解析布尔表达式

    Java C++刷题leetcode1106解析布尔表达式 问题描述 给你一个以字符串形式表述的 布尔表达式(boolean) expression,返回该式的运算结果。 有效的表达式需遵循以下约定: “t”,运算结果为 True “f”,运算结果为 False “!(expr)”,运算过程为对内部表达式 expr 进行逻辑 非的运算(NOT) “&…

    Java 2023年5月26日
    00
  • Java实现排队论的原理

    Java 实现排队论的原理 什么是排队论 排队论是一种数学模型,用来研究当需求超过资源时如何最优地使用资源。排队论可以用于优化系统、服务、流程等,以保证资源利用率最高并提供最佳的服务质量。 Java 实现排队论 Java 可以通过不同的算法和库来实现排队论的模型。以下是一些常用的 Java 库和算法: 1. SimJava SimJava 是一种面向对象的、…

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