java中的反射机制
七月的第四周,来写反射。
反射是java很有意思的机制,有一点注入灵魂的感觉。
写程序可以认为是女娲捏泥人的过程,女娲和了一团稀泥,揉捏出一个小人,放在地上,活了。
你设身处地想象一下,如果你是女娲造的其中一个小人,在落地之前一直都没有活。
那在你还没活的时候,你是不知道外面的世界长什么样子的,也不知道将来会遇到哪些小人。你不知道还有小王、小张、小李一起被造出来,你也不知道他们是什么样子的。
总之你只知道你自己的事情,你对其他的一无所知。
这就是你在活之前的状态。
写程序如果按照正常理解,就应该是程序运行,安分守己地完成自己的任务。
如果写了一个名叫 apple
的类,程序运行的时候, apple
就应该安分守己地做 apple
的事情,它不会知道,在程序中还有 banana
、 peach
、 watermelon
,也没有办法知道,除了自己以外的其他类能够做什么。
反射是做什么的呢?
就像是你刚被女娲捏出形状时,女娲对你说:“以后你将遇到一个叫‘小王’的人,记得找他玩。”然后你活了之后,果然找到了小王,愉快地跟他玩了起来。
程序在运行的时候,具有了访问别人的能力,甚至还能用别人的东西,这就是反射。
反射(reflect)是一个让人听了一头雾水的名字,但实际上确实也没有别的更好的表述方法,这就是一种比较难以形容的特性。如果暂时忘了这个名字,直接去理解这种特性,隐约理解之后再回来看反射这两个字,会稍微容易一些。
维基百科对于反射的描述,还是大概能看懂的,不然你试着搜搜百度百科的解释,当你精通概念之后回看才能勉强看懂。维基百科是这么说的:
在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。
java是一门具有动态性的语言,反射就是动态性的典型代表,这里的动态,说的就是程序正在运行。程序一边运行着,一边去查看自己的状态,然后做出修改,全程不停,就是动态。(但是java只能说有动态性,不能算动态语言)
反射的原理是较为复杂的,这里面涉及到java虚拟机相关的内容,我基本也是小白,尽量按照自己的理解写清楚。
打开编程软件之后,我首先创建一个文件,然后在里面写上一段代码,例如:
1 | public class Hello { |
这个文件,它的文件名是Hello.java
(就像是新建一个word文件,随便写了句话,保存之后文件名叫做Hello.doc
一样),现在这个文件的后缀名是.java
,这是我们的源代码文件。
你一定听过编译这个词,编译的意思是说,你写完代码之后,会有一种叫做编译器的东西帮我们把代码变成一堆010101……的二进制数字文件,也就是翻译成机器语言。编译器翻译完,会生成一个Hello.class
文件,这时这个文件的后缀名是.class
,这是我们的二进制流文件。
现在有了翻译给机器听的Hello.class
文件之后,这个文件就要加载进java虚拟机当中,让电脑自己去读程序运行了。java虚拟机读取Hello.class
文件的过程,是类加载过程。
我们今天说的反射,它的原理就是这个类加载过程。
类加载的具体过程比较复杂,涉及到java虚拟机的很多内容,我们来说简化的过程。
简单来说呢,.java
文件里写了很多代码,但是归归类可以分成这么几种:
- 干垃圾
- 湿垃圾
- 有害垃圾
- 可回收垃圾
java虚拟机中,也有相对应的区域,来分类存放写好的代码(以二进制数字的形式):
- 干垃圾桶
- 湿垃圾桶
- 有害垃圾桶
- 可回收垃圾桶
类加载就是一一对应,垃圾分类的过程。
反射就是要在垃圾分类之后,问垃圾管理员要垃圾。
你好,我是收废品的,请问有废易拉罐吗,给我一个。
我们再来重新看一下维基百科对于反射的定义:反射是指计算机程序在运行时可以访问、检测和修改它本身状态或行为的一种能力。
比如我想知道,某一个类,它叫什么,它有哪些成员变量。
java虚拟机会在类加载过程中,生成一个Class类的对象,比如我之前写的那个Hello.java
文件,java虚拟机将实例化一个Hello对象,我们之后可用直接用这个对象的各个方法,来进行反射操作(我们终于走到反射了)。
1 | Class testClass = Hello.class; |
所以现在,我们通过反射,可以获知某一个类叫什么名字、父类是什么、限定符是什么、有什么成员变量、有什么构造方法……等等关于这个类的一切,我想知道什么,全都可以知道了。
那么我们现在梳理一下步骤:
- 实例化一个Class类
- 调用这个Class类的方法,以获取到想要的东西
如果Class类的功能,你觉得不够用,或者用起来不顺手,还有别的几种类可以去用,分别是Constructor(构造方法)、Field(成员变量)、Method(成员方法)和其他。
相关的方法列表有人帮忙总结出来了,详见下图。
参考文献:
https://www.imooc.com/article/8021
https://docs.oracle.com/javase/tutorial/reflect/index.html
https://zh.wikipedia.org/wiki/%E5%8F%8D%E5%B0%84_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)
第一篇怎么写的这么烂呜呜呜……不改了,没时间了,到新的一周了= =