关注“Java后端技术全栈”

回复“000”获取大量电子书

反射是什么?

反射是Java程序开发语言的特征之一,它允许动态地发现和绑定类、方法、字段,以及所有其他的由于有所产生的的元素。通过反射,能够在需要时完成创建实例、调用方法和访问字段的工作。

反射机制主要提供功能

  • 在运行时判断任意一个对象所属的类

  • 在运行时构造任意一个类的对象

  • 在运行时判断任意一个类所具有的成员变量和方法

  • 在运行时调用任意一个对象的方法,通过反射甚至可以调用到private修饰的方法

  • 生成动态代理

反射在牛逼框架中的使用

  • Spring 框架的 IOC 基于反射创建对象和设置依赖属性。

  • Spring MVC 的请求调用对应方法,也是通过反射。

  • JDBCClass#forName(String className) 方法,也是使用反射。

反射中,Class.forName 和 ClassLoader 区别?

这两者,都可用来对类进行加载。差别在于:

  • Class#forName(…) 方法,除了将类的 .class 文件加载到JVM 中之外,还会对类进行解释,执行类中的 static 块。

  • ClassLoader 只干一件事情,就是将 .class 文件加载到 JVM 中,不会执行 static 中的内容,只有在 newInstance 才会去执行 static 块。

反射的常用类

Java中反射相关的类大部分都在rt.jar下java.lang.reflect中,其实需要的类并不多,主要有以下几个:

java.lang.Class

Class类的实例表示正在运行的Java类和接口。

java.lang.reflect.Field

提供有关类或者接口的属性信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。有点绕,慢慢体会吧。

java.lang.reflect.Constructor

提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Filed类封装类反射类的属性,而Constructor类则封装类反射类的构造方法。

java.lang.reflect.Method

提供关于类和接口上单个方法的信息。所反映的方法可能是类方法或者实例方法(包括抽象方法)。这个类不难理解,他的作用就是用来封装反射类方法的一个类。

java.lang.reflect.Modifier

提供了用于解码类和成员访问修饰符的静态方法和常量。修饰符集合被表示为具有表示不同修饰符的不同位位置的整数。

java.lang.reflect.Array

提供了动态创解决数组和访问数组的静态方法,该类中的所有方法都是静态方法。

反射的优缺点

优点

  • 可以在程序运行的过程中,操作这些对象。

  • 可以解耦,提高程序的可扩展性。

缺点

  • 因为是JVM操作,所以对于性能来说会有所下降。

  • 容易对程序源码造成一定的混乱。

探索 Class

java文件编译后变成class文件,class文件被类加载器加载到内存中,并且JVM根据其字节数组创建了对应的Class对象。

Class类是Java反射的起源,针对任何一个我们想使用的类,只有先为它产生一个Class对象,接下来就可以通过Class对象获取其他的信息。

JVM为每个类管理着一个独一无二的Class对象,当我们需要创建每个类的对象时,JVM会检查所要加载的类对应的Class对象是否已经存在。不存在,则JVM会根据类加载机制加载并创建对应的Class对象,最后使用Class对象创建出我们通常使用的实例对象。

获取Class类的三种方式

1.调用Object类的getClass()方法获得Class对象。

2.使用Class类的forName("com.tian.XXX")静态方法获取与字符串对应的对象(类或接口的全限定名)。

3.使用.class获取该类性的Class对象。

Class常用方法


方法非常之多。

获取类信息

了解了Java反射的详细细节之后,我们可以使用反射机制来获取类中的信息。

创建对象
使用无参构造方法创建对象

比如说下面这段代码:

Class clazz = Class.forName("java.lang.String");
String str = (String)clazz.newInstance();

这里需要注意,这个类必须是有无参构造方法,不然这种方式会报错的。

使用有参构造方法

可以使用三个步骤来完成:

1.获取指定类对应的Class对象

2.通过Class对象获取满足指定参数类型要求的构造方法类对象

3.调用指定的Constructor对应的newInstance方法,传入对应的参数值,创建出我们想要的实例对象。

Class clazz = Class.forName("java.lang.String");
Constructor constructor = clas.getConstructor(String.class);
String str = (String)constructor.newInstance("hello world");

这样就创建了一个String对象实例。

调用方法

前面已经聊过Method这个类,我们可以通过Method类中的invoke方法动态调用器方法。

public final class Method extends Executable {public Object invoke(Object obj, Object... args){//....}
}

这个方法的第一个参数是一个对象类型,表示要在指定的这个对象上调用这个方法(方法名称)。第二个参数是可变参数,用来给这个方法传递参数值;

invoke方法里返回的值用来表示动态调用指定方法后的返回值。如果调用私有的方法,先调用setAccessible(true)来曲线Java语言堆笨方法的访问检查,然后再调用invoke方法来真正执行这个私有方法。

访问成员变量的值

使用反射可以获取类的成员变量的对象代表,成员变量的对象代表是

java.lang.reflect.Field类的实例,可以使用他的getXyy()方法来获取指定对象上的值,也可以使用setXyy()方法来动态修改指定对象上的值,其中xyy是成员变量。

比如说:setAge(22);其中age就是成员变量。

操作数组

数组也是一个度一项,可以通过反射来查看数组的各个属性的信息,比如

ingt [] intArr=new Int[10];
Sysytem.out.prinlt("数组类型:"+intArr.getClass.getComponentType().getName());Object obj=Array.newInstance(int.class, 10);
//维数组赋值
for(int i=0;i<10;i++){Array.setInt(obj,i,i);
}
for(int i = 0;i<10;i++){System.out.print("第"+i+"好元素为"+Array.getInt(obj,i));
}

反射与动态代理

代理模式是Java中使用频率相当高的设计模式之一,尤其是在牛逼的框架中,Spring,Mybatis,Dubbo等框架中。

其中反射就是一个很好的应用。

静态代理模式我们就没有必要提他了,相当于一个业务需要代理,你就得给他搞一个代理类。全是手动搞出来的。

动态代理的原理就是,在程序运行时候根据需要动态地创建目标类的代理对象,典型应用场景:

  • JDK动态代理

  • CGlib动态代理

关于动态代理,后面有专门的文章分析。

到此我们的反射相关的意见讲完了。具体还是建议自己下去手动敲敲代码,体会一下,便于更深刻的理解。

总结

面试被问到,建议回答以下几个方面的内容:

1.反射是什么

2.提供了什么功能

3.常用类有哪些

4.优缺点是什么

5.其他框架中国的应用(动态代理)

推荐阅读:

《程序员面试金典》.pdf

《分布式Java应用基础与实践》.pdf

《Java并发编程的艺术》.pdf

吊打面试官系列:说说反射的用途及实现?相关推荐

  1. 重复订单号校验_吊打面试官系列重复消费、顺序消费、分布式事务

    你知道的越多,你不知道的越多 前言 消息队列在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在消息队列的使用和原理方面对小伙伴们进行360°的刁难. 作为一个在互联网公司面一次拿一次Of ...

  2. 【面试 - 八股文】Linux 高频面试题,助你吊打面试官系列

    继上次输出[面试-八股文]mysql 万字总结,助你吊打面试官,业界反响还不错 从 linux 基础.三剑客(grep\sed\awk).shell 脚本编程.文件管理命令.磁盘管理命令.网络通讯命令 ...

  3. 吊打面试官系列之---吃透MySQL mvcc机制--锁模块

    目录 事务四大特性(ACID) 事务并发访问引起的问题以及如何避免 1.更新丢失--mysql所有事务隔离级别都可以在数据库层面上均可避免 2.脏读--read-committed事务隔离级别以上可避 ...

  4. 2021Java不死我不倒,吊打面试官系列!

    前言 从3月份开始,打算找工作,一个偶然的机会,拉勾上一个蚂蚁金服的师兄找到我,说要内推,在此感谢姚师兄,然后就开始了蚂蚁金服的面试之旅.把简历发过去之后,就收到了邮件通知,10个工作日联系我,请耐心 ...

  5. 7年老Android一次坑爹的面试经历,吊打面试官系列!

    前言 刚从阿里面试回来,想和大家分享一些我的面试经验,以及面试题目. 这篇文章将会更加聚焦在面试前需要看哪些资料,一些面试技巧以及一些这次的面试考题. 一个朋友是前阿里人,37岁,离职后就职美团.以前 ...

  6. 330页PDF,10万字的知识点总结,吊打面试官系列!

    经历 坐标湖南,双非一本毕业.毕业后跟发小一起到深圳找工作.发小国防科大软件工程毕业.几乎没有太多周折,轻松入职了中国平安.像我这种双非渣本,随便在深圳拉一个外卖小哥出来学历可能都比我高. 前期找工作 ...

  7. 2020面试题合集之吊打面试官系列(一),kotlin数组性能

    参考回答:要测试Android应用程序,通常会创建以下类型自动单元测试: 本地测试:只在本地机器JVM上运行,以最小化执行时间,这种单元测试不依赖于Android框架,或者即使有依赖,也很方便使用模拟 ...

  8. MMKV集成与原理,吊打面试官系列!

    前言 校招 -1 年 这个阶段还属于成长期,更需要看重的是你的基础和热情.对于 JS 基础,计算机基础,网络通信,算法等部分的要求会相对高一些.毕竟这个阶段比较难考察你的业务项目中的沉淀,所以只能从基 ...

  9. 我在华为做Android外包的真实经历!吊打面试官系列!

    导语 本部分内容是关于Android进阶的一些知识总结,涉及到的知识点比较杂,不过都是面试中几乎常问的知识点,也是加分的点. 关于这部分内容,可能需要有一些具体的项目实践.在面试的过程中,结合具体自身 ...

  10. 吊打面试官系列:你会「递归」么?

    作者 | 小齐本齐 来源 | 码农田小齐(ID:NYCSDE) 递归,是一个非常重要的概念,也是面试中非常喜欢考的.因为它不但能考察一个程序员的算法功底,还能很好的考察对时间空间复杂度的理解和分析. ...

最新文章

  1. 中国电子信息产业发展研究院主办的2018中国软件大会上大快搜索“又双叒叕”获奖了...
  2. Docker(一):这可能是最为详细的Docker入门总结
  3. 示波器地线应用注意问题
  4. linux c之c语言符合标准的头文件和linux常用头文件
  5. Wannafly挑战赛24
  6. 极客青年说,北京沙龙
  7. java work stealing_Java线程池之WorkStealingPool,任务窃取算法
  8. 他一口气写出了这7k字的红黑树总结!看过的都说好!!|文末送书
  9. java实验报告13答案_(完整版)Java程序设计实验报告
  10. Could not find the main class: org.apache.catalina.startup.Bootstrap. Program will exit.
  11. Python爬虫实战03:用Selenium模拟浏览器爬取淘宝美食
  12. Redis六种底层数据结构
  13. uCharts图表在小程序中的使用
  14. SQLite数据库管理的相关命令
  15. oracle 导入DMP数据 imp 10g
  16. 【计量经济学导论】10. ARIMA模型
  17. Eyoucms易优小程序插件2.0版本上线
  18. 微信小程序,实现一个简易的新闻网
  19. 试题 基础练习 圆的面积
  20. 人生若只如初见,何事秋风悲画扇

热门文章

  1. oracle总结大全(dos中操作)
  2. 终身受益的健康小常识
  3. 面向对象数据库和NoSQL
  4. 三生石·奈何桥·孟婆汤
  5. 鬼门关、黄泉路、彼岸花、忘川河、奈何桥、孟婆汤、三生石
  6. java转义字符表_Java常见的转义字符
  7. Windows使用cmd静音,用DOS指令给Windows静音
  8. 记录一次不成功的换手机屏幕经历。
  9. inner.HTML与inner.Text的区别
  10. ASP.NET MVC 员工疫情信息管理