00:00
那下面的话呢,咱们就具体来展开说一下这里边儿的几个环节,那第一个过程呢,我们叫做loading,叫加载阶段,就是这个加载呢,大家别跟这个呢说混了,就是咱们说呢叫类的加载过程,这个加载过程呢,咱们说分成五个环节,那恰好这第一个环节呢,也叫做加载。解教的楼顶对吧,这个呢,咱们可以理解成叫广义上的加载,分成五个步骤,然后呢,这个其中第一个步骤呢,也叫做加载,这个呢,可以理解成我们讲的叫狭义上的这个加载,这个大家呢,区分一下就别看诶怎么这叫加载,这也加载,别蒙了啊。行,那关于这个第一个环节呢,我们看一下他主要做的这个事情是什么。说所谓的加载啊,简而言之就是将Java类的自解码加载到这个机器的内存当中,在内存当中啊,咱们构建Java类的一个原型,咱们称为呢叫类模板对象。类模板对象,所有的类模板对象呢,就是Java类,在Java信息中的一个,嗯,内存中的一个快照,将我们自解码文件中解析出来的,像常量值啊,这个类字段啊,类方法呀,这些信息咱们保存在这个类的模板当中。
01:03
啊,那使得呢,我们在运行期间,咱们呢,就可以通过反射来获取你这个类的任何信息。比如说你这个类中都有哪些成序变量啊是吧,我能不能调指定的某一个成现变量,某一个方法呀,这个其实呢,我们都是可以的,对吧?哎,这个一说到这儿呢,大家应该就想咱们这个反射,那能用反射的前提呢,是因为我们这个类的整体结构啊,已经被我们加载到这个内存中了。嗯,已经加载到了内存中了,对吧?那当然了,下边还有具体的一个验证啊,准备啊,解析啊这些细节,那我们现在只是说的其中的第一个环节而已,好那这个简而言之的话呢,就是我们说呢,呃,加载环节说你都干什么事儿了,就是查找。找到我们对应的资金码文件,把这个资金码文件,嗯,对应的这个二进制数据,像咱们刚才桌面上写的这,呃,放放过来这个,这不就是一个二进数,二进制的这个数据吧,把这个数据啊,咱们就一个一个的把这个二进制数据呢,加载到读入到咱们这个,呃,Java的这个内存当中,把它呢,生成你对应的这个大的class的一个实例。
02:09
这呢就是咱们加载环节主要做的事儿啊,具体来说呢,三个点,第一个通过类的全名获取类的二进制的数据流,把这个二进制的数据流拿到。对吧,把这个这个拿到这个类的全名这个知道啥情况吗。应该能理解,你比如说举个例子,比如说那那咱们就拿一个拿个这个这个来说吧。我这儿呢,你看这边写了个hello对吧,然后这个hello word呢,咱们打开它的这个。对应的打开错了,对应的整个这个目录结构。对吧,目录结构在这儿呢,然后在这儿呢,咱们进行一个CMD。Java c,然后我叫做hello word叫Java,那接下来的话呢,你看它就会生成咱们对应的这样一个自解码文件,对吧?这个自解码文件里边呢,实际上呢,它对应的是一个class叫hello word这个class,这个class呢,要想调我们得需要呢,使用它的一个全名,那我们这个Java程序呢,你看它是不是有个包名对吧,那这个包名呢,再带上它这个类名,这就是一个叫全类名,那现在呢,咱们这样写它是不OK的,你看一下。
03:21
Java下的哈喽。Word对吧,这时候你看我一回车,它其实我们找不到这个类,那其实呢,它应该是在我们这RCLC项,咱们这呢,其实就代表了像你这个全类名,所以我这块呢,得CD往往前得推几层这个目录啊,哎,在这个src下呢,此时我们再去执行刚才的这个Java,这呢就是我们是不是一个全类名啊,哎,通过这个全类名,那我们就找到你对应的这个资金码文件了。找到这个码文件了,然后呢,这个做的最初的事儿,就是把这个二进制的数据呢,加载进来,加载进来之后呢,生成我们方法区的整体的这个Java类的一个模板。
04:00
呃,这个障碍类的一个模板,那接下来的话呢,呃,有了这个模板之后,我们在这个堆当中,咱们还会生成一个大的克拉斯类的一个实例,这个实例呢,它就指向了你方法区的这个实际的这个模板啊,这就是我们说的这样的一个过程。啊,具体这样一个过程,咱们这儿呢,只不过是从最终效果上来看,这个没方法,咱们让他执行了,对吧?啊就是这个意思啊。好,这个事儿呢,大家要清楚,这是咱们谈的比较细的话呢,加载阶段做的三个事儿,那这里边呢,诶我们就一点点展开来说,比如说第一个环节呢,你就要获取类的二进制流数据,对吧?那有哪些方式来获取这个二进制数据呢?那我们这里边列举出来好几点,第一个就是我们最常见的这个场景,这个可能通过文件系统读入一个class后缀的文件,像咱们刚才这块呢,是不是就是啊直播呢,我们把这个点class呢给省略掉了。这呢,就是直接读取的我们对应的这个位置上的一个文件啊,这是一种还可以呢,我们去读入叫这或者zip这个相应归档的数据包提取那类文件,像咱们一些相关的一些插件是不是都是,诶我们把它打包到这个jar文件当中,对吧?嗯,还有呢,事先存放在数据库当中的二进制的数据,那像我们这样的这个数据,咱把它要存储到数据库当中,我们从数据库当中把它读出来,那也可以还原成内存中的一个类。
05:19
好,还可以呢,说使用类似于像HTP协议这样的,我们通过网络的方式呢,进行一个传输,然后进行一个加载,那像我们说使用的这个序列化呀,反序列化呀,对吧,这样的概念,我们都是相当于通过网络来进行数据传输,那我们再还原成内存中来提供成一个对应的类啊,然后还可以呢,在运行的时候,我们动态的去生成一段,只要呢,你符合大的class文件结构的是一个二进制的数据也可以。那前提呢,是你得符合相应的这个规范才行,所以说呢,只要你读这个二进制的这个数据是符合咱们讲的资金码规范的,不管是怎么样一种方式都可以啊,咱们见的比较多的呢,是咱们说的这个前两种。
06:00
哎,前两种,那在获取到这个二进制数据之后呢,咱们经过Java虚拟级的一个加载,那就主要呢,就是使用到咱们这里边儿这个类的加载器,对吧,对吧,它呢,加载到内存当中,在方法区生成一个类模板数据,那然后呢,我们在堆里边呢,生成一个大的class实例指向你这个方法区。那这个整个类模板数据就可以了。这里边还提到说如果输入的数据呢,不是class file这个结构就会报相应的这个error,那咱们呢,也讲到过,说呃,这个class是不是得符合规则,你像第一开始这个开BB,这就相当于得验证一下啊,凡是有这样一个魔术的,我们说它才至少才能可能是一个这个资金码文节,对吧,那你否则的话呢,叫开VB都没有,或者都不是,那就出问题了。那比如说哎,你看比如说咱们我把这个关掉,在咱们这块呢,我再使用这个打开啊,其实刚才那个就是对吧,然后在这块呢,我写一个1234吧。保存一下,显然呢,此时我是不是改变了这个四金码文件的一个开头啊,那关掉。
07:01
我保存了已经把它就关了,关完之后的话呢,你看我们再在这个位置上,咱们现在呢,如果再去进行一个解释运行,你看我一回车。大家会发现呢,你看这时候报的就是class form一个error,就是你这个自己码文件这个格式呢,不对是吧,那这呢,就是我们报的相应的这个错误信息。啊,错误信息行来这呢,就是我们说的这个事情。
我来说两句