首页 > 其他分享 >什么是反射

什么是反射

时间:2024-08-08 09:07:29浏览次数:5  
标签:反射 String 什么 Class 获取 clazz class

反射的概念
反射(Reflection)是 Java 的一种特性,它可以让程序在运行时获取自身的信息,并且动态地操作类或对象的属性、方法和构造器等。通过反射功能,可以让我们在不知道具体类名的情况下,依然能够实例化对象,调用方法以及设置属性。

image-20240807152333855

反射的作用
反射的作用有以下几点:

运行时探查类的信息:反射允许我们在运行时加载、检查和使用类,甚至可以在运行时获取一个未加载的类。

动态创建对象:使用反射可以实现动态地创建对象,而且可以选择该类的任意一个构造函数来创建对象实例。

访问或修改私有成员:反射可以访问和修改一个类中私有的字段和方法,即使这些字段和方法是私有的。

扩展应用程序的可控性:反射可以提高应用程序的可扩展性,例如,它可以读取配置文件来决定需要加载哪个类。

反射的特点
反射具有以下几个特点:

动态性:反射允许程序在运行期间动态地创建对象、调用方法和修改属性。

类型检查问题:虽然反射可以使用某个类的任何方法或属性,但是编译器在编译时并不会检查这些方法或属性是否可用。

性能问题:反射的性能比直接调用方法要差。因为在使用反射时,需要先获取方法或变量的引用,然后再进行调用或访问。

安全性问题:反射破坏了封装¥,可以对私有成员进行访问和修改

什么情况下使用反射
Java中的反射机制是指在程序运行时动态获取类的信息以及使用该信息来创建、操作和销毁对象的能力。下面是一些Java中使用反射的情况:

动态加载类:可以使用类加载器动态加载要使用的类,而不是在编译期间声明对该类的依赖关系。

获取类的信息:通过反射可以获取一个类的属性、方法、构造函数等信息,甚至可以获取注解和泛型信息。

通过名称调用方法或访问属性:使用反射可以根据方法/属性名称动态地调用/访问对应的方法/属性,这使得编写通用代码更加容易。

动态代理:使用反射可以实现动态代理,即在运行时动态地创建一个实现某个接口的代理类,从而实现一些特殊的功能,如事务处等。

需要注意的是,虽然反射提供了很大的灵活性,但过度使用反射会增加代码的复杂性和运行效率,因此应当谨慎使用。

工作流程

  1. 获取 Class 对象:首先获取目标类的 Class 对象。
  2. 获取成员信息:通过 Class 对象,可以获取类的字段、方法、构造函数等信息。
  3. 操作成员:通过反射 API 可以读取和修改字段的值、调用方法以及创建对象。

以下是 Java 反射的基本使用方式及其常见应用。

1. 获取 Class 对象

每个类在 JVM 中都有一个与之相关的 Class 对象。可以通过以下方式获取 Class 对象:

通过类字面量

Class<?> clazz = String.class;

通过对象实例:

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

通过 Class.forName() 方法:

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

2. 创建对象

可以使用反射动态创建对象:

Class<?> clazz = Class.forName("java.lang.String");
Object obj = clazz.getDeclaredConstructor().newInstance();

3. 访问字段

可以通过反射访问和修改类的字段:

Class<?> clazz = Person.class;
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
Object value = field.get(personInstance); // 获取字段值
field.set(personInstance, "New Name"); // 设置字段值

4. 调用方法

可以通过反射调用类的方法:

Class<?> clazz = Person.class;
Method method = clazz.getMethod("sayHello");
method.invoke(personInstance);

Method methodWithArgs = clazz.getMethod("greet", String.class);
methodWithArgs.invoke(personInstance, "World");

5. 获取构造函数

可以使用反射获取和调用构造函数:

Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("John", 30);

6. 获取接口和父类

可以使用反射获取类实现的接口和父类:

Class<?> clazz = Person.class;

// 获取所有接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> i : interfaces) {
    System.out.println("Interface: " + i.getName());
}

// 获取父类
Class<?> superClass = clazz.getSuperclass();
System.out.println("Superclass: " + superClass.getName());

以下是一个完整的示例,展示了如何使用反射来创建对象、访问字段和调用方法:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionExample {

    public static void main(String[] args) throws Exception {
        // 获取 Class 对象
        Class<?> clazz = Person.class;
        
        // 创建对象
        Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
        Object person = constructor.newInstance("John", 30);
        
        // 访问字段
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);
        System.out.println("Name: " + nameField.get(person));
        
        // 修改字段
        nameField.set(person, "Doe");
        System.out.println("Updated Name: " + nameField.get(person));
        
        // 调用方法
        Method greetMethod = clazz.getMethod("greet", String.class);
        greetMethod.invoke(person, "World");
    }
}

class Person {
    private String name;
    private int age;

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

    public void greet(String message) {
        System.out.println(name + " says: " + message);
    }
}

编译执行以上代码,输出结果为:

Name: John
Updated Name: Doe
Doe says: World

标签:反射,String,什么,Class,获取,clazz,class
From: https://www.cnblogs.com/ZWJ7671277/p/18348225

相关文章

  • 为什么 Python NewType 与 isinstance 和 type 不兼容?
    这似乎不起作用:fromtypingimportNewTypeMyStr=NewType("MyStr",str)x=MyStr("HelloWorld")isinstance(x,MyStr)我什至没有得到False,但是TypeError:isinstance()arg2mustbeatypeortupleoftypes因为MyStr是一个函数......
  • 尝试更新 GridDB 中的列,但无法弄清楚为什么它没有更新
    我正在尝试使用Python客户端更新GridDB容器中的数据。我已经设置了环境并编写了以下代码来执行更新。更新操作似乎不起作用,因为数据保持不变。关于我在这里可能做错了什么有什么想法吗?这是我正在阅读的文档:https://docs.griddb.net/gettingstarted/python/impor......
  • 为什么要用混合加密?
    首先我们需要先了解对称加密概念:采用单钥密码系统的加密方法,同一个密钥加密和解密,常用的对称加密算法DES、3DES、AES、RC2、RC5等。通俗的说就是你家大门锁和钥匙,你家里有都有大门钥匙来开这一把锁。那他有什么优点呢?1.加密计算量小,计算快,适合一些大数量......
  • 为什么并查集路径压缩不需要维护rank?
    在基于rank进行优化的并查集中,路径压缩确实不需要维护rank数组。这是因为路径压缩和rank优化有不同的目的和作用机制。让我们详细解释一下原因:Rank优化的目的:Rank优化的主要目的是在合并两个集合时,让较小的树成为较大的树的子树,以保持树的平衡性。这样可以避免树变得过于深,从而......
  • 雷达气象学(8)——反射率因子图分析(非气象回波篇)
    目录8.0雷达回波的分类8.1地物回波8.2海浪回波8.3干扰回波(同波长干扰)8.4生物回波8.5超折射回波8.6旁瓣回波8.0雷达回波的分类雷达回波可分为气象回波和非气象回波:\[雷达回波\begin{cases} 气象回波\begin{cases} 层状云降水回波\\ 积状云降水回波(对流性降水回......
  • 为什么用代理IP访问不了网站?如何解决?
    代理IP可以为用户在访问网站时提供更多的便利性和匿名性,但有时用户使用代理IP后可能会遇到无法访问目标网站的问题。这可能会导致用户无法完成所需的业务要求,给用户带来麻烦。使用代理IP时,您可能会因为各种原因而无法访问您的网站。下面小编结合自己的亲身体验,为你分享代理IP无......
  • 什么是大模型?快速了解大模型基本概念
    在人工智能的世界里,大模型就像超级大脑一样,能够处理和理解大量的信息。你可能听说过ChatGPT,它就是大模型的一个典型代表。那么,什么是大模型呢?让我们一起来探索这个神奇的领域。什么是大模型?想象一下,如果你的大脑能够记住整个图书馆的所有书籍,并且能够理解每本书的内容,那么......
  • java反射机制
    反射的原理Java反射机制概述JavaReflection(1)Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。(2)加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Cl......
  • 反射的用途
    反射的用途动态创建对象:使用反射,你可以创建任何类的实例,即使该类在编译时是未知的。动态访问字段:可以读取和修改私有字段的值,绕过Java的访问控制。动态调用方法:可以调用任何对象的方法,包括私有方法。动态获取类信息:可以查询类的名称、其父类的名称、其实现的接口......
  • 反射的优点和缺点
    反射的优点和缺点目录反射的优点和缺点优点缺点优点动态性:反射允许程序在运行时查询和操作对象,这为编写灵活和可扩展的代码提供了可能。通用性:通过反射,可以编写一些通用的代码,例如序列化工具、对象复制器等,这些工具可以处理任何对象。框架开发:许多现代Java框架,如Spr......