Java反射技术原理与用法实例分析

 更新时间:2020年04月15日 10:24:10   作者:随风行云  
这篇文章主要介绍了Java反射技术原理与用法,结合实例形式分析了Java反射技术的基本概念、功能、原理、用法及操作注意事项,需要的朋友可以参考下

本文实例讲述了Java反射技术原理与用法。分享给大家供大家参考,具体如下:

本文内容:

  • 产生反射技术的需求
  • 反射技术的使用
  • 一个小示例

首发日期:2018-05-10


产生反射技术的需求:

  • 项目完成以后,发现需要增加功能,并且希望增加功能并不需要停止项目运行。
  • 在希望不关停项目运行的情况下,于是考虑到将功能都放到一个单独的项目之外的模块中,每一个功能实现都从这个模块中获取【实际上这个考虑应该是项目开始前就考虑,这个例子可能不是很好】。于是就有了反射的产生。(这种思想有点类似工厂模式,如果学过设计模式的话就明白为什么要做的”开放“)

一个帮助理解例子:

一个网站有计算器功能,刚开始他们只有加减乘除的计算,后来他们决定增加上求乘方、求根号的计算,他们通过“关停网站后修改源代码“来增加上他们需要的功能。第二次,他们加上xx功能,他们还是关停网站加功能。。。。后来他们发现应该把这个”功能模块“独立出来,任何功能实现都通过读取这个文件来实现,比如想要实现乘方功能就需要查看这个模块中是否定义了乘方功能。另外,将它独立出来后,它一个模块并不影响整个板块的功能。

【上面的例子中,其他板块如果想要知道独立的模块的内容(属性、方法),那么就要利用到反射技术,反射技术可以使程序在运行时解析外部对象的信息。】

PS:

  • 上面的例子有点像某系统从数据库中读取资料,把资料固定到代码中显然是一个很不明智的行为,把数据存到数据库中,再利用SQL语句(类比反射技术)从数据库中读取数据就降低了代码之间的耦合。
  • 如果你希望将这个模块有一个名词解释的话,可以把它称为”配置文件“,有什么功能都可以读取配置文件来获取。下面就是讲怎么从外部的”配置文件“中读取具有什么属性和功能了。

如果你已经了解了 为什么需要反射,那么你可以继续向下了,如果不了解,那么你可能需要了解更多再深入。


反射的使用:

  • 反射技术是一种动态语言的技术,它可以动态的获取类以及类中的成员,并可以调用该类成员。

获取外部字节码文件中的类:

  • 对于内部的类,获取该类的对象时我们可以使用newimage
  • 但是如果字节码文件中获取类的话,需要Class类,如果通过Class类获取了一个字节码中的类,那么我们再可以直接new这个来获取一个对象。
    • 对于代码中的类,可以使用 类对象.getClass()来获取一个字节码文件对象。image
    • 对于代码中的类,也可以使用 类.class 来获取一个字节码文件对象。image
    • 对于外部代码中的类,可以使用Class.forName("类字节码文件路径")来获取一个字节码文件对象【这个类字节码文件是classpath中能够识别的路径,eclipse中会自动加上一部分classpath】【eclipse中,在每一个project的目录下都有一个classpath来标明字节码文件和源代码文件的位置】【在eclipse中可以方便地使用包名.类名来获取字节码文件image

获取外部类的对象(获取构造方法):

  • 获取字节码文件中的类对象后,可以使用newInstance()来生成一个对象。image
  • 直接使用Class对象.newInstance()生成的对象默认是调用对应类的空参构造方法实例化生成的对象。
  • 但没有空参数的构造方法时:
    • 1.首先需要获取构造方法来生成指定的对象,可以使用getConstructors()来获取所有构造函数,getConstructor(参数类型列表)来获取符合参数列表的构造方法;【1.这里对于getConstructor注意参数类型列表不是数据类型+变量名,而是一个个Class:数据类型.class】image【2.Constructor是一个存放构造器的类。】【3.获取的构造方法应该是public的】
    • 2.然后再利用构造器对象.newInstance(参数列表)来实例化对象。image
    • 如果是非public的构造方法,可以使用getDeclaredConstructor(参数类型列表)来获取构造方法。同样的,getDeclaredConstructors()是获取所有不论public还是非public的构造方法。

获取外部对象的属性:

  • 首先通过Class对象获取变量域field:image【Field类用来存储变量域】
    • getField(变量名):获取指定变量名的public的成员变量
    • getFields():获取所有public的成员变量
    • getDeclaredField(变量名):获取不论public还是非public的指定变量名的成员变量
    • getDeclaredFields():获取不论public还是非public的所有成员变量
  • 然后使用Field对象来操作:
    • 赋值:Field对象.set(对象名,变量值)image
    • 获取值:Field对象.get(对象名)image

获取外部对象的方法:

  • 首先通过Class对象获取方法域method:image【Field类用来存储方法域】
    • getMethod(方法名, 参数类型列表):获取public的指定名的方法
    • getMethods():获取public的所有方法
    • getDeclaredMethod(方法名, 参数类型列表):获取不论public还是非public的指定名的方法【用来获取私有的方法】

    • getDeclaredMethods():获取不论public还是非public的方法

  • 然后使用Method对象操作:

    • 非静态方法调用:Method对象.invoke(对象名,对象名…)image

    • 静态方法调用:Method对象.invoke(null)image

补充:

  • 如果想使用普通方法就能访问私有的变量或属性,可以使用:field.setAccesccible(true)


一个小示例:

1.读取”软件列表“:

image

2.通过读取功能列表来获知类的字节码的路径

image

3.开发"软件”:

image

3.给软件列表加上内容:image

4.运行

更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • Java中实现在一个方法中调用另一个方法

    Java中实现在一个方法中调用另一个方法

    下面小编就为大家分享一篇Java中实现在一个方法中调用另一个方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • Java编程实现springMVC简单登录实例

    Java编程实现springMVC简单登录实例

    这篇文章主要介绍了Java编程实现springMVC简单登录实例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 详解Java 打印堆栈的几种方法

    详解Java 打印堆栈的几种方法

    本篇文章主要介绍了Java 打印堆栈的几种方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • java实现堆排序以及时间复杂度的分析

    java实现堆排序以及时间复杂度的分析

    本文主要介绍了java实现堆排序以及时间复杂度,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • java的GUI实现简单切换界面

    java的GUI实现简单切换界面

    这篇文章主要为大家详细介绍了java的GUI实现简单切换界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • java获取键盘输入的数字,并进行排序的方法

    java获取键盘输入的数字,并进行排序的方法

    今天小编就为大家分享一篇java获取键盘输入的数字,并进行排序的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Java中Vector与ArrayList的区别详解

    Java中Vector与ArrayList的区别详解

    本篇文章是对Java中Vector与ArrayList的区别进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • Java ThreadLocal详解_动力节点Java学院整理

    Java ThreadLocal详解_动力节点Java学院整理

    ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,本文会详细的介绍一下,有兴趣的可以了解一下
    2017-06-06
  • Spring Retry 重试实例详解

    Spring Retry 重试实例详解

    这篇文章主要介绍了Spring Retry 重试,使用方式有两种分别是命令式和声明式,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-10-10
  • Java如何不解压读取.zip的文件内容

    Java如何不解压读取.zip的文件内容

    这篇文章主要给大家介绍了关于Java如何不解压读取.zip的文件内容的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论