博客
关于我
Java反射
阅读量:793 次
发布时间:2023-01-28

本文共 3616 字,大约阅读时间需要 12 分钟。

反射是Java中的一个强大机制,允许我们在运行状态中动态地获取类、对象的属性和方法信息,进行操作。尽管在大多数情况下我们并不直接通过反射编写代码,但了解反射的重要性对理解现实中许多技术,如Spring中的动态代理和各种RPC实现,有着不可替代的作用。

反射的概念

反射机制使我们能够在不了解类具体结构的情况下,获取其属性和方法,并对其进行动态调用。这涉及到两类操作:一个是对类的反射,另一个是对对象的反射。

  • 类反射:通过类的反射,我们能够获得类名、类的加载器、类 declaredMethods 和 declaredFields 等信息。
  • 对象反射:通过对象的反射,我们可以访问对象的属性,调用对象的方法,甚至重写其方法。

通过反射,我们可以在程序运行时,根据需求动态地获取和使用类或对象的信息和方法,这在企业级应用中具有极其重要的意义。

以下是一个简单的反射示例:

public class TestReflection {    public static void main(String args[]) {        try {            Test obj = Test.class.newInstance();                        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));            String s = br.readLine();                        Method m = Test.class.getDeclaredMethod(s);            m.invoke(obj);        } catch (IOException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {            e.printStackTrace();        }    }}class Test {    public void sayHello() {        System.out.println("Hello");    }    public void sayWorld() {        System.out.println("World");    }}

在这个程序中,我们通过反射获取用户输入的方法名称,并调用对应的方法。如果我们输入 "sayHello",程序会打印 "Hello";如果输入 "sayWorld",程序会打印 "World"。

反射的作用

反射的主要作用在于reaking the code的复用性和灵活性。我们可以通过动态读取函数名和参数来调用系统中的任何函数,这使得程序在运行时能够基于输入或其他外部条件进行操作,而无需在程序编写时就硬编码。

以下是一个更复杂的反射应用示例:

public class TestReflection {    public static void main(String args[]) {        Test obj = Test.class.newInstance();        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                String methodName = br.readLine();        String param1 = br.readLine();        String param2 = br.readLine();                try {            Method m = Test.class.getDeclaredMethod(methodName, int.class, int.class);            int a = Integer.parseInt(param1);            int b = Integer.parseInt(param2);                        System.out.println(" 调用方法:" + methodName + " 参数:" + a + "、" + b);            m.invoke(obj, a, b);        } catch (IOException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {            e.printStackTrace();        }    }}

在这个程序中,我们可以根据输入的方法名称和参数来调用不同的函数。这使得程序能够灵活地处理各种情况,比如动态处理系统中的任何功能。

动态加载类和属性

通过反射,我们不仅可以动态地操作方法和属性,还可以动态地加载类和修改对象的属性。以下是一个动态加载类的示例:

public class TestReflection {    public static void main(String args[]) {        try {            Test obj = Test.class.newInstance();            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                        String fieldName = br.readLine();            String className = br.readLine();                        Field f = Test.class.getDeclaredField(fieldName);            Class
clazz = Class.forName(className); Object value = clazz.newInstance(); f.set(obj, value); obj.sort(); } catch (IOException | NoSuchFieldException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } }}class Test { public Sorter sorter; public void sort() { int[] a = {5, 7, 3, 1, 4, 6, 2}; sorter.sort(a); for (int i : a) { System.out.println(i); } }}

在这个程序中,我们可以动态地修改对象的属性,并调用排序算法。这使得程序在运行时能够动态使用不同的排序实现,而无需预先编写代码。

练习建议

  • 从标准输入改为读取文件内容:可以将输入从标准输入改为读取文件内容,然后尝试一一替换,看看如何通过反射动态地改变程序行为。
  • 动态测试不同的算法:在排序类中使用不同的实现,例如改用插入排序或归并排序,然后通过反射来测试不同的排序类。
  • 反射在现实应用中具有广泛的应用范围,比如Spring框架的动态代理、DYNAamic Proxy等。通过反射我们可以在程序运行时动态地调配和组合各种功能,这大大提高了程序的灵活性和可维护性。

    通过理解反射机制,你可以更好地理解依赖注入(Dependency Injection)和其背后的原理。反射机制使我们能够在容器中动态地注入不同的实现,这与依赖注入的思想非常接近。希望今天的课程能为你打开反射的世界之门,带你领略Java语言的强大能力。

    转载地址:http://wiryk.baihongyu.com/

    你可能感兴趣的文章
    Kubernetes实战(二十八)-环境共享与隔离(Namespace)
    查看>>
    Kubernetes实战(二十六)-高可用负载均衡与外部服务(Service)
    查看>>
    Kubernetes实战(二十四)-kubernetes二进制文件方式部署集群(安全)(下)
    查看>>
    Kubernetes实战(二十)-kubernetes二进制文件方式部署集群(非安全)(下)
    查看>>
    Kubernetes实战(五)-亲和与互斥调度策略(PodAffinity)
    查看>>
    Kubernetes实战(八)-定时任务(Cronjob)
    查看>>
    Kubernetes实战(六)-污点与容忍(Taints 和 Tolerations)
    查看>>
    Kubernetes实战(十一)-包管理工具(Helm)
    查看>>
    Kubernetes实战(十七)-动态存储供应(StorageClass)
    查看>>
    Kubernetes实战(十三)-标签选择器(Label)
    查看>>
    Kubernetes实战(十九)-kubernetes二进制文件方式部署集群 (非安全)(上)
    查看>>
    Kubernetes实战(十二)-集群资源监控工具(metrics-server)
    查看>>
    Kubernetes实战(十五)-敏感数据管理(Secret)
    查看>>
    Kubernetes实战(十八)-共享卷子路径划分(Subpath)
    查看>>
    Kubernetes实战(十六)-存储卷管理(PV & PVC)
    查看>>
    Kubernetes实战(十四)-配置管理(ConfigMap)
    查看>>
    Kubernetes实战(十)-升级和回滚(Deployment)
    查看>>
    kubernetes实际生产中遇到的问题及解决办法
    查看>>
    Kubernetes容器日志处理方案
    查看>>
    Kubernetes容器集群管理环境 - Prometheus监控篇
    查看>>