前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >围绕Java反射,BAT的面试官可以问出多少花样

围绕Java反射,BAT的面试官可以问出多少花样

作者头像
王炸
发布2020-02-26 11:47:19
6161
发布2020-02-26 11:47:19
举报
文章被收录于专栏:转行程序员

好久不见,在疫情的控制下,我急需一杯奶茶续续命!

作者:王炸 |【坚持1000篇原创】

2020.2.21 王炸的第60篇原创

☝️先赞后看是技术人的传统美德☝️

有小朋友问我,我刚刚学Java,没接触过项目,也没机会用Spring之类的框架,看书也知道反射都有什么内容,哪本书都说反射很有用,但到现在都不知道它用在啥上面,所以,反射有啥用?

关于反射,我必须要吐槽一下,初学的时候如果靠看xxx从入门到精通系列的书,理解反射可太TM困难了,看的我怀疑人生,那个时候我一度怀疑,我该不是个智障吧!

今天来分析下:围绕Java反射,BAT的面试官可以问出多少花样。

反射关系到Java的语言特性,jvm的内存细节

JVM:只能跑Java代码的CPU

刚刚开始我也不理解Java的虚拟机到底算个什么东西?

第一节接触这东西一脸困惑,字节码代码是在CPU上执行?在虚拟机上执行?虚拟机又是个什么东西?

后来我慢慢试着理解:JVM就是跑才CPU上的一个虚拟CPU,但是这个CPU只能跑Java代码

Java之所以能跨平台就是因为这个东西,你可以理解成一个进程,程序,只不过他的作用是用来跑你的代码的。

上图是java的内存模型,我们关注的点,一个方法区,一个栈,一个堆,初学的时候老师不深入的话只告诉你java的内存分为堆和栈

假如你写了一段代码:String s=new String();

运行了起来!这里面发生了什么?

  1. 首先JVM会启动,你的代码会编译成一个xxx.class文件。
  2. 然后被类加载器加载进jvm的内存中(虚拟CPU),你的类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象每个类只有一个class对象,作为方法区类的数据结构的接口。 ⚠️注意:jvm创建对象前,会先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。

上面的流程就是你自己写好的代码扔给jvm去跑,跑完就over了,jvm关闭,你的程序也停止了。

为什么会发明反射这种技术?

想想上面的程序对象是自己new的,程序相当于写死了给jvm去跑,程序员都是聪明的动物,还有没有更好的办吧不用写死,不用new。

假如一个服务器上突然遇到某个请求哦要用到某个类,哎呀但没加载进jvm,是不是要停下来自己写段代码,new一下,哦启动一下服务器,(脑残)!

这个时候反射技术诞生了,这在当时,是一个非常先进的理念,Java也因此得到更多人认可。

反射是什么呢?

当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,这样的好处对于服务器来说不言而喻。

Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射。

有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类,这时第一个程序员不能通过编译,但是利用反射就可以通过。原因是java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。

举个例子:

我们的项目底层有时是用Mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了。

假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用。

这时候我们的程序就写得比较动态化,通过Class tc = Class.forName("com.java.dbtest.TestConnection");

通过类的全类名让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。

这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!

举多个例子,大家如果接触过spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。

好吧,围绕Java反射,BAT的面试官可以问出多少花样

面试:Java反射机制在Spring IOC中的应用

IOC:即“控制反转”,不是什么技术,而是一种思想。

使用IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

IOC底层实现的原理(反射),Bean容器的实现,就不对IOC的概念进行详述了。

在Spring的配置文件中,经常看到如下配置:

代码语言:javascript
复制
<bean id="courseDao" class="com.qcjy.learning.Dao.impl.CourseDaoImpl"></bean>

那么通过这样配置,Spring是怎么帮我们实例化对象,并且放到容器中去了了?对,就是通过反射!!!

面试:Java反射在动态代理中的应用

JDK动态代理

Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

  1. Interface InvocationHandler:该接口中仅定义了一个方法Object,invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。
  2. Proxy:该类即为动态代理类。
Cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。JDK代理要求被代理的类必须实现接口,有很强的局限性。而CGLIB动态代理则没有此类强制性要求。简单的说,CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。

Javassist代理

一种是使用代理工厂创建,另一种通过使用动态代码创建。使用代理工厂创建时,方法与CGLIB类似,也需要实现一个用于代理逻辑处理的Handler;使用动态代码创建,生成字节码,这种方式可以非常灵活,甚至可以在运行时生成业务逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 转行程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 今天来分析下:围绕Java反射,BAT的面试官可以问出多少花样。
    • JVM:只能跑Java代码的CPU
      • 为什么会发明反射这种技术?
        • 反射是什么呢?
          • 举个例子:
        • 面试:Java反射机制在Spring IOC中的应用
          • 面试:Java反射在动态代理中的应用
            • Javassist代理
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档