博客
关于我
Java反射
阅读量:792 次
发布时间: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/

    你可能感兴趣的文章
    EasyUi的使用与代码编写(一)
    查看>>
    ECSHOP实现收货国家省市由选择下拉菜单改为手动
    查看>>
    ECShop模板原理
    查看>>
    edgeboxes proposal 和dpm 连接
    查看>>
    EdgeX Foundry:开启边缘计算新时代
    查看>>
    Edge浏览器打开控制台后程序总是停止进入debug模式关闭教程【八仙过海之又一过海方案】
    查看>>
    Educational Codeforces Round 28
    查看>>
    ed编辑器--适用于shell脚本内编辑文件的最最简单编辑器
    查看>>
    EF 资料
    查看>>
    Effective Modern C++:02auto
    查看>>
    efficientnet最合适的尺寸和最后一层的层数
    查看>>
    Ehcache Java开源缓存框架
    查看>>
    EJB学习笔记六(EJB中的拦截器)
    查看>>
    el-form表单重置后输入失效
    查看>>
    el-select下拉框修改背景色
    查看>>
    el-table select事件判断当前项是否勾选
    查看>>
    Elasticsearch & Kibana & Filebeat开启SSL通信
    查看>>
    ElasticSearch - DSL查询文档语法,以及深度分页问题、解决方案
    查看>>
    ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)
    查看>>
    ElasticSearch - 基于 docker 部署 es、kibana,配置中文分词器、扩展词词典、停用词词典
    查看>>