00:00
那关于密封类呢,咱们就介绍到这儿啊,大家也看到这个密封类呢,应该是非趁用的,它呢作为一个preview啊预览的特性,在将来的版本中就会做一个正式版的确定下来。那实际上这个蜜蜂类呢,在之前的skyla语言当中已经出现过了,所以这呢也可以看作是从skyla语言借鉴过来的一个特性,那主要呢,是为我们后期做模式脾胃呢提供了一个前提,好,那这呢是我们说的第一个特性,然后接下来的话呢,咱们来看第二个特性叫做隐藏类。那隐藏类呢,对应的是GP371这样一个编号,嗯,叫做hidden classes。隐藏类对吧,那刚才呢,我们提到叫做密封类,把这个类呢,给它密封起来限制呢,呃,被此类呢所这个继承对吧?那我们只能通过promise的方式呢,指定哪个哪些类呢,作为它的一个,呃,哪些类呢,去继承这个对应的密封类,而我们这个隐藏类的话呢,从字面意义上来看呢,是要隐藏起来。
01:02
那目的是什么呢?来,咱们看一下下面的说明。说该题啊,通过启用标准的API来定义无法发现,并且呢,具有有限生命周期的隐藏类啊,这呢,大家看到提到了两个词,第一个呢叫做无法发现。啊,这呢,我标成一个红色的是吧,第二呢叫具有有限生命周期,那怎么叫无法发现呢?那我们会发现呢,这个隐藏类呢,它只可以通过反射的方式呢进行访问,是没有办法呢,在其他的类的字节码中直接来进行调用的。啊,这呢,我们说呢,一个类里边你调另外的类啊,相应的在资金码中也会体现相应的一些指令,对吧,那这呢,我们说到它是不可以直接呢进行其他类的一个调用的,那说明呢,它是在运行的时候呢,咱们动态生成的这样的一些类。啊,这就使得它呢,无法被直接呢发现啊,那就不能够直接的被调用了。那么正因为呢,它无法被其他的类自检码呢,直接被调用,所以说呢,它的这个加载和卸载,尤其是卸载。
02:06
那就非常的容易了,那我们说呢,这个类呢,通常都是存在于呃,我们称为它叫这个方法区当中的,对吧?那方法区中这个类呢,如果说方法区内存不足了,调用这个for GC的话呢,我们说一般情况下呢,都很难把这个类呢进行卸载。啊,为什么这么讲呢?因为呢,呃类呢,首先它会涉及到相关的其他类的一些关联,以及呢,要想卸载一个类呢,哎,我们说类跟它对应的类的加载器也有个相互的一个引用关系,那类的加载器呢,相当于也得是呃没有用了,对吧?哎,我们才会进行一个类的卸载,所以类的卸载呢,整体来讲呢,是非常悲壮的啊,通常呢,不会具有很好的一个回收的效率了,所以说呢,当我们这个类呢,它在运行的时候呢,动态的生成的,而且呢,它不能被其他类呢直接来访问,这就使得呢,它在卸载方面呢,就非常的轻松。啊,这样呢,能够减少咱们框架的一个内存占用啊,所以说呢,它是具有有限生命周期的啊,就是这样的概念,那基于这两点呢,我们能够提供啊,提高了这个GM呢语言上的一个执行效率问题啊,体会一下这样一个问题啊,这个有限生命周期啊,体现了GM我们在使用的时候减少内存占用了它的一个效率问题啊,就是想用的时候呢去加载,不想用的时候呢,我们可以直接进行卸载。
03:20
那通常来说呢,基于GM的很多语言呢,都具备这种动态生成类的一个机制啊,这样的话呢,就能够提高语言的一个灵活性和一个效率啊,比如说呢,我们在GM上呢,诶是不是也有这个GS这个程序可以进行执行的,对吧?那么javascript的引擎呢,它就可以呃为这个GS这个程序转化成的这个字节码呢,去生成这种隐藏的类啊,因为呢,当引擎不再使用它们的时候呢,这一类呢,就可以直接呢进行一个卸载啊,提高了这种灵活性和效率啊,那具体来说呢,说我们这个黑class是怎是什么呢?怎么来理解呢。诶,你看我下边这块写的啊,说这个所谓的hidden class呢,就是不能够直接被其他的class的二进制代码所访问的这个啊,使用的这个class。
04:06
啊,它呢只能够被一些框架啊,用来生成运行式的类,而这一类呢,不是直接被使用的,只能够通过反射的方式呢来进行调用啊其实上面上面我们也都提到过了,对吧?在这呢,也举个例子就提到了,像我们正儿八引入的这个拉姆达表达式,在编译的时候呢,拉姆达表达式呢,它并没有呢去转化成专门的类,而是在运营的时候呢,根据相应的直接把动态生成相应的类的这个对象。啊,因为咱们知道拉va的表式啊,你叫一个匿名函数也行,在咱们Java当中呢,它仍然是作为一个对象出现的是吧,作为我们那个函数是接口它的一个,呃,匿名实现类的一个对象出现的,对吧?那这儿呢,就提到了一个动态的去生成在运行时环节体现的,那举个例子啊,比如说呢,呃,咱们在这个代码中,我这块写一个啊,我这写一个就叫做哎拉姆达。在这呢,我就写一个这个类方法啊,啊,比如说呢,咱们针对这个像reable这个接口,那它呢,就属于一个函数接口对吧?哎,这个右边的话呢,我们对应的就是这个转方法,那是没有参数的,在这个具体的拉姆达体当中,我们就写一个哈,那就可以了,行,那这时候我们就写了一个非常简单的一个拉姆达表达式啊,那这个拉姆达表达式的话呢,我们把它作一个编译。
05:22
好编译好了对吧,那编译完以后呢,呃,大家呢,这时候比如说你去看这个自节码文件啊,诶我们打开这是这个刷新一下是吧,就它了,把它打开之后呢,你看给我们反编译之后呢,它还是这样的一个形式。那还是这样的一个形式,就是你这时候呢,看不出来说诶是不是编译完以后右边呢,就会我们对应的是一个对象的形式呢,没有还是一个拉表达式,所以编译的时候呢,没有去生成你这个类对象啊嗯,那对应的呢,它是在运行的时候才出现的,那对应的我们就在相应的这个自节码指令当中啊,我们使用一下这个接开lab啊,大家呢,就会看到你看这时候我们这个main方法,这个code这块使用了一个指令叫invoke dynamic。
06:04
啊,就是动态的去进行一个加载。啊,那这个VO dynamic呢,它就是呃,调用这个动态绑定的一个方法了啊,这个指令呢,是在咱们JDK1.7的时候呢引入的啊,它主要呢,是用于在运营的时候呢,动态的解析书,咱们调用点限定符所引用的这样一个方法。啊,这就提到这个动态调用这样一个问题啊,好,包括呢动态代理,那我们也是为了动态的去生成一些相关的类啊。那么动态生成的这个类有什么特点呢?第一个叫不可发现性啊,因为我们是为了某些静态的类呢去生成的动态类,所以说呢,这个动态类呢,就不能直接被发现了,它只能够通过这个静态类去发现,那访问控制,那我们去控制静态类啊,那就对应的就控制在这个动态生成类,那生命周期我们说它比较短对吧,那对应的API层面的知识呢,下边就提到这样的一些啊,我这呢就不多去解释了啊,那么现在也下边是一个复习。咱们普通的一些类就是非隐藏的类,咱们呢,呃,底层都是通过class loader啊,对应的一个叫DeFine class,那我们以二进制流的方式呢,去加载你对应的字节码文件二进制的数据,对吧,然后把它呢,生成内存中的一个大的class的一个对象,而我们这里提到这个隐藏类呢,它是通过这个lookup叫DeFine hidden class这样的方式呢,去进行一个加载。
07:23
哎,通过这样方式进行加载啊,而对于我们GM来讲呢,他认为这种方式也好,还有这种方式也好,加载过来以后呢,是没有呃任何区别的啊,它是一个呃平等对待的啊,所以呢,就使得我们这个隐藏加载这一类呢,在运营的时候呢,也能够正常的去使用啊,这就可以了,好,这里边呢,大家关于这个hidden classes呢这块,哎,整个也是做一个熟悉啊就行,这呢也是我们之前呢没有提到过诶明确提到过这样的一个概念啊,这呢我们就引入来。
我来说两句