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日

相关文章

  • JVM调优笔记(一)–Nacos GC引发的服务批量下线问题

    故障背景 线上批量发服务下线的告警邮件,偶发nacos连接超时。采用了spring boot admin(以下称sba)进行服务监控。 原因分析 因为sba服务是基于nacos对其它服务进行监控,所以遇到这个问题,第一怀疑对象是nacos发生问题,但不清楚具体是什么问题。由于服务过一段事件会恢复,所以nacos肯定是没有挂掉的,那么排查方向应该是针对naco…

    Java 2023年4月23日
    00
  • Java 类与对象超基础讲解

    Java 类与对象超基础讲解 什么是Java类与对象? Java是一种面向对象编程(OOP)语言,具有类与对象的概念。 类(Class)是Java中一种用户定义的数据类型,用于定义对象的属性和方法。 对象(Object)是类的一个实例,是Java中真实存在的实体。 类与对象的关系类似于模板与山寨货的关系。类是设计图纸,而一个具体的对象则是由这张设计图纸所呈现…

    Java 2023年5月26日
    00
  • Java超详细讲解类的继承

    Java超详细讲解类的继承 什么是类的继承 类的继承是一种面向对象编程语言中非常重要的概念。它允许子类(派生类)继承父类(超类)的公有方法和属性,这样子类就可以重用父类的代码,同时还可以扩展父类的功能。 为什么要使用类的继承 使用类的继承有以下几个优点: 代码重用:子类可以继承父类中的方法和属性,从而减少代码量,提高代码的重用性。 细节隐藏:子类不能访问父类…

    Java 2023年5月26日
    00
  • 浅谈springmvc的DispatcherServlet分析

    浅谈SpringMVC的DispatcherServlet分析 SpringMVC是一种基于MVC模式的Web框架,它可以帮助我们快速开发Web应用程序。在SpringMVC中,DispatcherServlet是一个核心组件,它负责接收所有的HTTP请求,并将请求分发给相应的处理器。本文将详细讲解SpringMVC的DispatcherServlet,并提…

    Java 2023年5月17日
    00
  • jQuery Ajax传值到Servlet出现乱码问题的解决方法

    下面是详细的攻略: 问题背景 在使用 jQuery Ajax 技术将数据传递到 Servlet 后台时,有时会遇到中文乱码的问题,这是因为在传输过程中,字符编码格式不统一,导致原本正确的中文字符被解析成乱码的字符。 解决方法 为了解决这个问题,我们需要对字符编码格式进行统一,可以通过以下两种方法实现。 解决方法一:手动设置字符编码格式 在 jQuery Aj…

    Java 2023年6月15日
    00
  • Java实现的最大匹配分词算法详解

    Java 实现最大匹配分词算法详解 什么是最大匹配分词算法? 最大匹配分词算法是目前中文分词中最简单、最易于实现的一种方法。该算法采用正向最大匹配或逆向最大匹配的方式,将整段文本按照给定的词典进行分词,从而得到一个完整的分词结果列表。 最大匹配分词算法的实现步骤 读取待分词的文本和词典,将词典中的所有词按照长度从大到小进行排序,这是为了保证匹配时能够优先匹配…

    Java 2023年5月19日
    00
  • jsp response.sendRedirect不跳转的原因分析及解决

    针对“jsp response.sendRedirect不跳转的原因分析及解决”,以下是完整攻略: 1. 确认response.sendRedirect是否执行 首先要确认response.sendRedirect是否真正执行了。可以通过在response.sendRedirect前后,分别加入System.out.println语句,输出一些信息,在控制台…

    Java 2023年6月15日
    00
  • Spring IO Platform简单介绍

    下面我就为您介绍一下“Spring IO Platform简单介绍”的完整攻略。 1. Spring IO Platform简介 Spring IO Platform是一个基于Spring的生态系统,为使用Spring的开发人员提供了一个完整的解决方案。它包含了许多Spring生态系统中最常用的库,使开发人员可以更加轻松地构建复杂的应用程序。Spring I…

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