您的位置 首页 java

干货 | 详解Java反射机制

反射是程序在运行状态下,动态的获取某个类的内部信息的一种操作。例如:类名,包名,所有属性的集合,所有方法的集合, 构造方法 的集合等。该操作发生在程序的运行时状态,所以编译管不着有关反射的一些代码,通常只有在运行时才能暴露出程序的内部错误。反射的核心在于‘Class’这个类,本篇将从Class这个类开始介绍有关反射的一些基本的概念,主要内容如下:

  • 获取Class对象
  • 从Class对象中读取字段信息
  • 从Class对象中读取方法信息
  • 获取Class对象中的所有构造方法并使用它们动态创建类对象
  • 反射的一些其他细节

一、获取Class对象

此处的Class是一个具体的( Java .lang.Class)并不是我们自定义一个类时所使用的关键class。这是一个泛型类,通常有两种方法可以获取该对象。第一种方式,使用类名.class来获取Class对象。

干货 | 详解Java反射机制

无论是基本数据类型,还是一般的class类型,或是接口类型,都是可以通过.class的方式来获取与之对应的Class对象。第二中获取Class对象的方法是,通过getClass方法,当然不是所有类都提供了这个方法的,例如:Object类就提供这么一个方法:

干货 | 详解Java反射机制

还有我们的数组类型:

干货 | 详解Java反射机制

下面看看有关我们获取到的这个Class对象的一些基本信息。首先我们可以获取有关该Class对象的名称,包,父类,父接口等信息。

干货 | 详解Java反射机制

还有一些有关注解的信息,由于之前在介绍注解的时候已经说明过,此处不再赘述。上面的这些方法的使用还是比较简单,此处不再演示。

二、获取Class对象中字段信息

类中的字段包括实例域和静态域。在Java反射机制中,使用Field类管理字段信息。

干货 | 详解Java反射机制

对以上四种获取字段Field的方法做一点说明,getFields或者getField方法可以看见该类所有的被public修饰的字段,包括从父类继承的,但是不可见非public修饰的字段。getDeclaredFields或者getDeclaredField方法可以看见该类所有的字段,包括非public修饰的,但是不可见父类中的字段。接下来,我们看看对获取到的field字段可以做哪些操作:

干货 | 详解Java反射机制

对于以上的几个基本的方法,可以说见名知意,这里需要说明的是get和set方法,先看个例子:

干货 | 详解Java反射机制

这里的 f 代表了 school这个实例属性,如果别的类中有相同的属性,我们是可以通过 f为该属性赋值的,当然也可以从某个具有该属性的类中获取该属性的值,前提是具备目标类中的该属性的访问权限。上述的getModifiers返回的是int值,该值代表了一个修饰符,想要转换成我们能看懂的字符串的形式需要使用 Modifier.toString(int a)方法,将刚刚返回的int值作为参数传入即可。

三、获取Class对象的方法信息

无论是静态方法还是实例方法,在Java反射机制中都是使用Method这个类来管理的,一个方法对应于一个Method对象。先看怎么通过Class对象获取其中的方法。

干货 | 详解Java反射机制

对于以上四个方法需要说明一点的是,getMethod或者getDeclaredMethod在获取指定方法的时候,需要传入该方法的形参类型,如果没有传入或者传入错误就会抛出NoSuchMethodException异常。因为方法名和方法参数类型(个数)是唯一确定一个方法的凭据。对于获取到的Method方法有以下一些操作:

干货 | 详解Java反射机制

上述方法中的invoke方法和之前介绍的字段的get/set方法一样,需要指定目的对象才能使用,因为他们只是代表了具体的一个字段或者一个方法。

干货 | 详解Java反射机制

四、获取构造方法和创建实例对象

一旦我们获取到了Class对象,我们就可以通过以下的方法进一步获取其中的构造方法,并使用它们创建一个实例对象。

干货 | 详解Java反射机制

以上的方法和之前介绍的字段Field,方法Method很是相似。下面我们看看如何使用Constructor做一些事情。

干货 | 详解Java反射机制

我们主要看看如何通过 newInstance 创建一个实例对象:

干货 | 详解Java反射机制

五、反射机制的一些细节

前面我们一直讨论的都是具体的类,我们可以从这些类中获取到字段,方法, 构造器 ,注解等。java.lang.reflect包中对数组类型增添了专门的类Array来实现反射,这里的Array和数组中的Arrays是不同的。

干货 | 详解Java反射机制

我们可以通过Array类在运行时动态创建数组和操作数组中的元素,而不必想之前一样必须在编译之前完成数组的创建。需要注意的是此处返回的数组类型是Object而非Object[],那时因为前者可以转化成具体类型的数组,后者则不能。

至此,反射的基本内容介绍完了,我们应该知道,虽然反射很是灵活,可以动态的读取类的信息,动态的创建实例对象和数组等,但是没有了编译器的一层检查,很容易导致运行是异常。如果能够用接口来完成的,尽量使用接口来完成。


最后,我自己是一名从事了多年开发的Java老程序员,辞职目前在做自己的Java私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的Java学习干货,可以送给每一位喜欢Java的小伙伴, 想要获取的可以关注我的头条号并在后台私信我:01,即可免费获取。

文章来源:智云一二三科技

文章标题:干货 | 详解Java反射机制

文章地址:https://www.zhihuclub.com/195722.shtml

关于作者: 智云科技

热门文章

评论已关闭

6条评论

  1. Savage MO, Wilkinson AR, Baum JD, Roberton NRC 1975 Furosemide in respiratory distress syndrome

  2. 165 NAS derivatives were found to be sensitive and versatile probes for AS aggregation, and convenient for monitoring in continuous assay methods, thereby providing useful tools for studying the mechanisms of amyloid formation

  3. Our case series and systematic review of the literature supports the indication to stop tamoxifen during pregnancy and reinforces the need to provide adequate information on contraception to patients undergoing adjuvant endocrine therapy

  4. The absence of endogenous OAT1 and OAT3 expression in ciPTEC was demonstrated by exposure to fluorescein 1 ОјM for 10 min, which did not increase the intracellular fluorescence intensity as measured by flow cytometry Fig Epinephrine Injection Epinephrine Injection The metabolism of Tamoxifen can be decreased when combined with Epinephrine

网站地图