Java的十五篇:反射

音乐的浪漫之处在于:它能将封存的记忆迅速拼凑起来,你会清晰的记起当时,听这首歌的感觉和状态,就像时空真的倒回某一刻。


// 获取 Spring 的 IoC 容器,并根据 id 获取对象
public static void main(String[] args) {
// 1.使用 ApplicationContext 接口加载配置文件,获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
// 2. 使用反射机制,根据这个字符串获得某个类的 Class 实例
IAccountService aService = (IAccountService) ac.getBean("accountServiceImpl");
System.out.println(aService);
}

另外,Spring AOP 由于使用了动态代理,所以也使用了反射机制,这点我会在 Spring 的系列文章中详细解释。

Java的十五篇:反射


jdk 的class

Java的十五篇:反射
img

所以拿到这个类后,就相当于拿到了咱们想解剖的类,那怎么拿到这个类?

Java的十五篇:反射
img

看API文档后,有一个方法forName(String className); 而且是一个静态的方法,这样咱们就可以得到想反射的类了

Java的十五篇:反射
img

到这里,看Class clazz = Class.forName(“com.cj.test.Person”);这个应该有点感觉了吧

Class.forName(“com.cj.test.Person”);因为这个方法里接收的是个字符串,字符串的话,我们就可以写在配置文件里,然后利用反射生成我们需要的对象,这才是我们想要的。很多框架里都有类似的配置


Java的十五篇:反射


扩展:

1、除了上述的Spring配置文件里会用到反射生成bean对象,其他常见的MVC框架,比如Struts2、SpringMVC等等一些框架里还有很多地方都会用到反射。

前端夜页面录入的一些信息通过表单或者其他形式传入后端,后端框架就可以利用反射生成对应的对象,并利用反射操作它的set、get方法把前端传来的信息封装到对象里。

2、框架的代码里经常需要利用反射来操作对象的set、get方法,来把程序的数据封装到Java对象中去。

如果每次都使用反射来操作对象的set、get方法进行设置值和取值的话,过于麻烦,所以JDK里提供了一套API,专门用于操作Java对象的属性(set/get方法),这就是内省

3、平常用到的框架,除了配置文件的形式,现在很多都使用了注解的形式。

其实注解也和反射息息相关:使用反射也能轻而易举的拿到类、字段、方法上的注解,然后编写注解解析器对这些注解进行解析,做一些相关的处理


Java的十五篇:反射

点个在看你最好看

Java的十五篇:反射


总结:

1.反射拥有以下四大功能:

  • 在运行时(动态编译)获知任意一个对象所属的类。
  • 在运行时构造任意一个类的对象。
  • 在运行时获知任意一个类所具有的成员变量和方法。
  • 在运行时调用任意一个对象的方法和属性。

上述这种动态获取信息、动态调用对象的方法的功能称为 Java 语言的反射机制。

反射的具体原理:

在通常情况下,一定是先有类然后再 new 一个对象出来的对吧,类的正常加载过程是这样的:

首先 JVM 会将我们的代码编译成一个 .class 字节码文件,然后被类加载器(ClassLoader)加载进 JVM 的内存中,同时会创建这个类的 Class 对象存到堆中(注意这个不是 new 出来的对象,而是类的类型对象)。JVM 在创建这个类对象前,会先检查其类是否加载,寻找类对应的 Class 对象,若加载好,则为其分配内存,然后再进行初始化 new 操作。

OK,那么在加载完一个类后,堆内存的方法区就产生了一个 Class 对象,并且包含了这个类的完整结构信息,我们可以通过这个 Class 对象看到类的结构,就好比一面镜子。所以我们形象的称之为:反射。

2.优点:比较灵活,能够在运行时动态获取类的实例。

缺点

1)性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的 Java 代码要慢很多。

2)安全问题:反射机制破坏了封装性,因为通过反射可以获取并调用类的私有方法和字段。

反射在我们实际编程中其实并不会直接大量的使用,但是实际上有很多设计都与反射机制有关,比如:

  • 动态代理机制
  • 使用 JDBC 连接数据库
  • Spring / Hibernate 框架(实际上是因为使用了动态代理,所以才和反射机制有关,这个地方可以酌情扩展)

3.通过反射我们可以获取到私有方法里面的属性,也可以通过反射扩展或者节省我们的代码,让我们的代码更加优雅!

4.通过反射,也就是调用了 getClass() 方法后,我们就获得了这个类类对应的 Class 对象,看到了这个类的结构,输出了类对象所属的类的完整名称,即找到了对象的出处。

5.知道了动态加载类,通过反射实现了*动态加载类

Java的十五篇:反射




本篇文章来源于微信公众号: 小刘Java之路

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/11291.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!