00:00
好,那么刚才的话呢,我们是举了相关的这个例子啊,通过这例子呢,大家去体会一下我们反射的一个应用,诶大家呢,今天建立一个感性的一个认识了啊,然后回到我们这个课件这个层面呢,我们再来看一下,诶这块呢,就提到了这个首先的话呢,这里边说,诶我们为什么把刚才在讲到的这样的一些操作涉及到一篇呢,把它称为呢,叫反射是吧,给它起了个名,这个反射这个词呢,我们在其实中学当中都接触过了是吧。中学当中啊,应该是在先回忆一下我们上学的时候吧,啊,现在是初中的时候,应该先接触这个光的反射,应该是讲物理的时候说的是吧。对,这不就跟这个一样吗?这个光线呢,从这打过来,这有个叫入射角是吧,这个叫啥。法线对有的已经记不住了是吧,然后呢,这块呢,就是这个出射角了啊,然后入射角跟这个出射角呢,它俩这个角度是一样的。哎,这呢叫反射是吧,哎,光这样打过去,诶这样过来啊,这叫光的反射,然后后来呢,上高中的时候呢,又讲过这个生物当中的这个反射是吧。
01:02
反射弧对,其中有一个叫膝跳反射嘛,啊,这块这块假设就是你是吧,这膝盖这块呢,一敲人翘一下是吧。这个叫膝跳反射了啊,它呢对应的有个反射弧,对应这块一敲的话呢,诶整个的这个。哎,这个这个相当于这个反射的这个神经是吧,呃,直接呢,就从下边呢,一直传到你大脑当中,然后大脑当中呢,然后再反射回来啊这个膝盖呢,这块跳了一下,呃,膝跳反射,OK,这个呢就是生物当中讲的,那现在的话呢,我们学这个编程这块呢,有一波API啊,它也叫做反射,说我们这块怎么去理解呢?诶这块呢,我形象点呢去说,虽然说这块呢,我们还没有去通过API呢,去做这个事儿,但是呢,我们是可以做这个事儿的,你比如说以前的时候呢,咱们都是先呢有包。创建个包,然后包里边的话呢,我们说明一个类,然后通过这个new的方式呢,去造这个类的对象,然后在那取得这个实例化的这个对象。啊有包有泪,然后有对象了,然后现在的话呢,我们可以通过反射来理解,这呢,就好比是这个入射的这个光线啊,诶从前往后,然后我们通过反射呢,可以理解成呢,叫反过来,假设呢,我们现在已经有一个具体的内存中的对象了,我通过这个对象呢,可以看一下你是哪一个类创建的。
02:14
然后呢,我们也能够啊,根据这个类呢,看看这个类呢,是在哪个包下声明的。有点像呢,就是反过来了啊,先有对象,有对象呢,我们说到你所属的类,呃,根据你所属类呢,我们再找到你所在的这个包,原来呢都是这样的,现在这个就是反过来了。哎,稍微的通过这样一个小例子啊,大家去感受一下,叫做反射是吧,然后再要是嗯,通过一个小的细节呢,去体会一下呢,就比如说咱们刚才写的这个例子当中哈,像以前的时候呢,咱们都是对象调属性对调方法。啊说这块呢,呃也有反过来的一天是吧,这块呢成了呢,诶就是从我们这个实际意义上来看啊,似乎呢,就变成了属性,你不是A类型的一个属性嘛,属性呢呃调对象啊方法呢调对象。
03:01
有点像这个意思一样。当然了,你这个,呃,从我们这个语法上来看的话呢,这正常呢,这还是一个对象,这还是对象调的一个方法,传递一个参数是吧,只不过从我们实际意义上来讲,似乎呢,就是有点像这个呢,叫收方法了,这个收方法呢,呃,发起了对这个对象调用一样。呃,稍微的简单的体会一下就行,有点这种反射的这种感觉啊,OK,然后从我们这个内存的角度来看的话呢,这呢是咱们当初编写的一个Java类啊,Va原文件里边的这样一个类,然后编译完以后呢,这不是我们生成叫四基码文件嘛,这个C码文件的话呢,我这使用16进制去查看的,就长这样了,然后呢,我们把这个4G版文件呢,就加载到内存当中了。啊,这个呢,其实我们这截了个图,还是一个自解码文件了,但是你想象成了就是内存空间当中,诶有这样有关于我们这个类的所有的信息。诶,都放在这个方法区的这个位置了,然后呢,我们在这个堆空间里边呢,你可以调用你当前这个类里边这个构造器,然后我们创建相关的这个对象,哎,简单的大家先理解一下就可以了。
04:00
好,那么整体来看呢,通过反射我们能做什么事呢?刚才呢,我们演示了一些例子,除了那些例子之外呢,那这块呢,整体来看一看,我们呢,可以在运行的时候呢,判断任意一个对象呢,所属的类。然后呢,可以去构建任意一个类的对象,可以呢,判断任意一个对任意一个类呢所具有的成员变量和方法。不管你是私有的还是非私有的都能够看到啊,都有哪些结构,然后呢,可以在运营的时候呢,获取这个泛型的信息,哎,可以在运营的时候呢,调用任意一个对象的成员变量和方法,诶这个在运营时候呢,处理注解,生成动态代理,动态代理的话呢,后边讲像spring啊这个框架的时候呢,我们到时候再说这个代理模式啊,代理的这个事儿。好这块呢,就是我们通过反射能能做的事儿,这里边儿呢,其实你主要呢,就看到有任意这两个字。可见呢,这个反射的功能还是比较强大的啊,然后对应的相关的API呢,诶我们提到这个class,刚才呢,我们在演示的时候呢,这不也用到了相关的这样的几个类吗?这几个类呢,是在浪包的这个子包啊,叫做reflect这个子包下的。
05:00
那所以呢,我们跟反射相关的一片呢,基本上都处在这样的一个包下。只有呢,这个class呢,它是在这个浪堡下呢出现的,整个呢,关于反射的优点缺点是什么呢?诶大家看看能不能理解啊,这个优点的话呢,说提高了Java程序的灵活性和扩展性,降低了耦合性,提高了自适应能力,这个呢,大家恐怕现在理解的还不是特别到位。这个咱们得随着这讲解的这个深入呢,我们再去说他这个事儿啊,所以呢,允许呢,程序创建和控制任意类的对象,无需呢提前应编码目标类这个呢,其实就是体现了它这种动态性,这个我们也稍后呢去看一看再啊。好,就是这章讲完之后呢,我们再来理解,大家能够清楚呢就可以了,那下一个呢,说提到反射的这个性能较低啊,包括呢,我们这个编码的时候呢,它呢,导致我们整个代码量会增加,口头性呢也会比较差一些。那这个呢,就是它相关的这种缺点啊,这个我们做一个理解就可以了啊,主要呢,我们还更多的看重的是它的优点,也正因为呢,它有这两个优点,所以呢,我们在框架当中呢,才会去使用这个反射,OK。行,这儿呢,我们就是呃,再说明一下这个反射的这个特点,好,那么接着的话呢,回到咱们刚才写的这个例子这个层面哈,然后呢,我们看这个T2也行,看这个T3呢也可以,诶这里边诶我们会发现呢,诶你把这个光标呢,放到这个class这块,放到这块的时候呢,你发现呢,我们接下来做的几个事儿呢,都跟它有关系。
06:15
这呢是我们一个变量,你看首先呢,我们要调离构造器的时候呢,诶由它呢发起的出来这个constructor,然后下边呢,诶construct呢再去操作,然后呢,由这个class发起呢,我们去获取了一个指定的属性,由他发起呢,我们去调了一个相关的这个结构,返回的是一个具体的方法,你会发现呢,我们要想到对象调属性,调方法,都跟这个class这个变量呢有关系,而它呢又是我们这个大的class这个类型的。所以这块呢,我们就有必要呢,来讲一讲这个大的class,而它呢也作为咱们反射的一个源头出现。整个反射的相关的操作呢,都由它引发出来,从他这个名字上你也能看到它还是比较特别的一个类的,所以呢,这块我们就先来讲讲关于大的class的一个理解的问题。好,那不妨呢,我们就以刚才呢这个person是吧来说,或者说这块呢,我们又换了一个类呢,叫做user,那里边的基本的信息呢,看都没有什么变化啊,不管是哪一个类,这个类的话呢,诶,我们对它使用的过程当中啊,其实呢,就会体现这个大的class了,怎么来理解呢?哎,这块我来写啊。
07:18
关于大的class雷迪这块又回归到咱们讲的第一天授课的时候呢,我们提到这个Java c和这个Java的这个操作。哎,这儿呢,我们说啊,针对于呃编写。哎,好的。啊,编写好的,呃,咱们说那叫点Java,这个叫原文件是吧,进行编译。哎,这个编译的话呢,我们这儿呢说呢使用。哎,是不是Java c.exe这个指令是吧?哎,那么针对于我们编译好的,点Java呢,原文件呢进行编译啊,会生成啊一个或多个,呃,点class的叫自解码文件。
08:02
啊,这是我们说的这样一个编译的过程啊,然后接着的话呢,啊。我们使用啊叫java.e这样的一个指令,或者叫命令呢,对啊,我们指定的。啊,咱们这个迪class文件。进行解释运行是吧。哎,进行解释运行在这呢,就是我们讲的前面说的这样一个过程哈,然后呢,这个解释运行的过程当中。诶,过程中说我们需要呢,将咱们这个点class这个自解码文件呢,加载到内存中。啊,那么我们说呢,加载到。啊,内存中的这个点这个文件。哎,对应的这个结构。
09:02
啊,对应的这个结构。啊,极为。啊,咱们这个大的class的一个实力。诶这个同学呢,可能有点懵是吧,诶我们这块呢,稍微的再解释一下啊,你比如说诶咱们这个呢,文件person也好,这个UC也好,这呢其实是对应的一个点点Java的一个呃原文件了哈,然后我们编译完以后的话呢,诶针对于我们当前这样一个文件里边呢,就只有这一个类的话呢,它就会生成一个叫user.class这样一个资金码文件。好,然后呢,我们使用这个java.e这个命令呢,对这个磁解码文件呢,我们进行一个解释运行,说白了就是我们要把它加载到内存里了,然后呢,诶加载到内存中呢,我们这呢就个叫。哎,内存中里边呢,就是相当于叫user.class了,那么加到内存中的这个user这个类。啊,我这个结构的话呢,没有明确说呢,啊,比如说你是个类,也可能是个接口啊,也可能是其他的一些结构。只是说呢,我们比较常见的话呢,是一个类,那么加载到内存中的这个类,比如我们这个user类,就作为了我们大的class的一个实例。
10:08
啊,这儿呢,我们说,哎,比如说加载到。哎,我说内存中的啊,叫person类。哎,然后或者呢,比如说这个,诶死菌类是吧,哎或者说呢,我们刚才提到这个叫user类。哎,他们呢,都作为咱们大的class的一个一个的实力。哎的一个一个的这个,哎实例。哎,就这样,那我们怎么去表示呢?咱们按照前面这个思路来讲呢,我们不是这样写过吗?说大的class这呢,比如说我们叫诶CLASS1吧,诶加载到内存中的这个类,我怎么去体现这个类呢?前面我们写法呢,是这样的写过。啊,那这时候你可以再换成另外的这个,比如我们这个string是吧,你要写的话,那不就这样写吗。哎,三的话呢,这个比如说user,哎就这样写。
11:01
这个注意啊,咱们不是说这个小自解码文件了,这个呢,加载到内存中的话呢,它其实就是一个完整的一个结构了。啊,只是说呢,你要是物理磁盘上的是要加class,然后这呢,就是内存当中,但是你又内存中你要写的话,你又不能这样写。这样话这样写的话呢,我们认为呢,它是一个解是一个类型了是吧?哎,那你这块呢,加个点class呢,它其实就是一个实体的一个值了,这个值呢,就是它的一个实例。啊,稍微的体会一下啊,那么这个解释运行过程中呢,我们把它加载到内存当中了,那这块就提到说加载,那么谁来加载的呢。哎,在这我们多这个说一句哈,这个呢,加载我们是使用了叫类的加载器。诶,就是专门有一个结构呢,叫做类的加载器,它呢负责呢,把我们这个文件呢加载到内存中。哎,加到那内存中,内存中在哪儿呢?哎,这话我说呢,诶存放在方法区。这个内存结构的话呢,我们不是说呢,有一个方法区的一个结构吗?那就放在这个方法区里边,I呢,就是这个person.class string.class user.class包括呢,我们相关的一些接口也是如此哈,比如我们前面提到这个叫诶compar这个接口,如果呢,你要需要用到这个接口,这个接口呢架到内存中,它呢也对呢,是一个大的class的一个实例。
12:18
哎,我们这个class的话呢,它指向的不一定是一个类哈,诶可能呢,还是个接口,还有可能是其他的接口呢,哎,我们靠后一点的时候呢,到时候再说啊。行,呃,那么我们加载到内存中的这个person类,String类或者user类,因为它是加载到内存里了,我们呢,也给大家起个名称为呢,叫做运行时的一个类。那就意味着我们下边这仨呢,就他们仨哈,其实都是运营室类。啊,就是运行的时候,因为你是通过这个指令加载了,这叫运行时候哎的一个类了啊。好,那这块的话呢,我们对这个大的class呢,大家有一个理解啊,相当于的话呢,就是原来呢,我们说有一个类呢去造对象,现在说呢,这个类本身呢,又是另外一个类的对象。
13:03
而这个类谁呢?就是大的class。啊,这个稍微的大家找找这种感觉哈,呃,你比如说你像以前的时候呢,咱们都怎么着呢,说呢这是一个person是吧,Person的话呢,可以创建不同的对象。啊,这个对象的话呢,你看都具备这个person里边的这样的一些结构,比如说person类呢,生命有属性name a,还有相关的方法啊,然后呢,你造的这个对象呢,是不是大家呢,也都有相应的一些A值,Name属性,包括一些相同的方法。是吧,然后呢,Animal呢也类似啊,有你自己生命的属性方法,然后你造出来的这两个对象呢,也具备你这些属性方法。那么大家换个角度来说,Personally也好,Animal也好,这个类的话呢。你想想我们前面讲这个面向对象的时候提到了,说类里边呢,你就一定会有属性,一定会有构造器,可能还会有一些方法是吧,这呢都作为这个类的一些通用的结构,诶那是不是我们专门再有个结构呢,就是用来描述类呢。是吧,那就出来一个叫描述类的一个类啊,这块我们叫做大的class,而我们具体的这个类呢,就作为它的一个实例了。
14:08
哎,所以说呢,我们说这个类本身呢,也可以看作是大的class的一个实力,或者叫一个对象。哎,这个意思啊,好,你再举一个,呃,也不是那么恰当的一个例子啊,你比如说咱们这个翻字典的时候呢,看到一个词,这个词呢,后边呢,就是它的一个解释。这个我们把它呢,通常称为呢一个概念了。那这个词呢,现在就有一个词叫概念,是不是还得用一个概念去解释。啊有点绕了是吧,诶类呢去诶这个派升对象类的话呢,又可以看作是呢,我们另外一个类呢,它相应的一些这个呃结构的特征啊,派生出来的啊就这样一个意思啊好这块呢,我们先对这个大的class呢,大家有个直观的一个理解,好那么有了这个大的class以后呢,我们才可以展开对于反射整个的一个使用,那刚才我们也说过了啊,由它呢引发出来的,我们可以做下边的这样的一些事情了,所以我们把这个大的class呢,就看作是反射的一个源头了,既然呢它这个源头,我们就有必要呢来了解一下,说如何获取大德克拉斯实力,否则的话呢,这个反射呢,就没法开展了。
15:09
这块我们就提一下获取大的class实例的几种方法,诶这块呢,有几种呢,我会想讲四种啊,四种里边呢,前三种是需要大家掌握的。那这边我们就开始来写啊。哎,大的class的关于它的一个测试啊。哎,这呢,我写一个单词方法。那这第一个哈啊,这个测试的话呢,我们主要呢,是做这个事儿,获取大的class实力的几种方式,那其实呢,我们已经呢讲了一种方式了,比如针对这个user的话呢,咱们就直接呢叫user.class。这个呢,我们就拿一个大的class呢,去做一个接收。哎,就这样写了,这呢,其实就是我们说的一种方式,诶,我们可以理解为呢,叫调用这个运行实例的一个静态属性。啊,运行时类的一个,呃,静态的一个属性。哎,这个属性的话呢,就是这个class这个属性OK啊行,那调完以后的话呢,直接呢,就获取这个大的class实例了,哎,这个你要愿意打印一下的话呢,你看看也行。
16:09
这呢,我们做一个,哎,执行。得到的话呢,就是我们这样的一个结构。OK啊行,第二呢,是我们说的第一种方式啊,然后呢第二种方式,第二种方式呢,其实以前我们也见到过啊,你比如说我现在已经有了优色的一个对象了。诶这么着是吧,在这个user这个类里边呢,我们这有个空的构造器啊好回过来我就调了一个空单的构造器,造了一个对象了,然后通过这个对象呢,咱们在object里边呢,不是有个方法叫get class吗。哎,这个get class呢,我们说呢,就获取你当前这个对象呢,所属的类。那拿到你这个类了,你的这个类呢,不就是这个运营实类吗,不就充当了我们这个大的class的一个实力了吗。哎,就是这样一个方式啊,所以这块呢,我们称为呢叫调用啊运行时类的对象的,哎,叫get class的这个方法。
17:01
OK啊,这个方法呢,是咱们object当中的一个方法。好,这呢是CLASS1,这是CLASS2,诶我这就不打印这个CLASS2了哈,这块呢想问个问题啊,这时候我们想看一看这个CLASS1是否等等于这个CLASS2。等等,就意味着比较他们的地址是吧。说是不是同一个呢。这块呢,我们对一运行,你发现了它的结果呢,是一个触是吧。那就意味着说这两个呢,实际上呢,是同一个。大的class的实力了。指向的都是他。哎,那就意味着你看我们这时候呢,用的时候,你可以理解成叫首次使用。这时候在使用的时候呢,如果内存中没有,咱把这个类呢,就加载到了,比如这叫占,这叫对,这叫方法区域,然后这个user这个类呢,我们就放到这个方法去了,放进来以后呢,咱们就会把它呢给缓存起来了。啊,还原起来的意思呢,就是说我们不会说呢,马上用完就把它给销毁掉了。这个注意啊,那当然有同学就问说,诶,我要是出了这大框呢,是不是把它就删掉了呢。
18:03
其实也没有。啊,其实也没有关于它的一个,呃,咱们说那叫清理,呃,咱们原来也提到过GC的话呢,主要是来回收堆的是吧。方法区的话呢,其实也能回收,但是回收的效果很差。也就是说呢,我们虽然出了这个大括号呢,按说呢,我们这个类呢,似乎不用了,但是也没有回收成。啊,当然有同学会说说你这块有没有东西指向你了,为啥还回收不成啊?只是我们看到没有谁指向了,其实还有指向。哎,这一说呢,有点多了啊,就是还有那个类的加载器,类的加载器呢,还指向它了,所以导致这个呢,其实并没有回收。所以说呢,我这块用个词呢,就是把它给缓存起来了,缓存的就意思呢,就不会说马上就销毁啊好,那我们下边这块呢,通过这个对象呢,去调这个get class说为什么得到还是它呢。因为你看我上面把它加载过来以后,你这块你有一个user,这是不是构造器啊。我用这个构造器的时候呢,我就会去方法区里边去找,说这个类呢有没有,如果没有我就加载一看是不是有了。
19:04
有的话呢,我就不会再去加载这个类了,我就直接呢,从你现成的这个类里边呢,调你构造器,这不就造了对象了,自然而然的,你再去看看这个对象呢,是谁造的,那不还是这个类吗。所以呢,我们这时候呢,这个类呢,我们说只会加载一次哈。诶这块大家注意一下回过来,诶我们把这儿呢,也稍微的去提一下啊,这写这个说明。哎,说呢,我们这个运行十类啊,在内存中会缓存起来。诶会缓存起来啊,然后呢,呃,在整个。啊,这个执行期间。啊,只会啊加载一次。这个整个执行期间呢,你可以理解成是在整个我们这个基本上就是GM的一个执行期间了。啊,他呢,只会加在一起一次啊,当然这句话呢,其实不够严密,诶如果大家你以后学了这个GM的话呢,你可能回过来说说这句话呢,写的是有问题的。
20:04
啊,这呢,会涉及到呃一个什么事呢,我们讲到这个类的加载器的时候呢,稍微的再提一提啊好,暂且的话呢,大家就认可这个事儿就可以了,好那么接着呢,我们再回过来。啊,回到我们这个层面啊,这呢就是我们说的这个第二种方式啊,得到的是同一个大的class的一个实力了,好第三个点。诶,除了我们上面提到这两种方式,以前咱们还见过之外呢,还有一种方式就是我们去调用这个大的class,它的这个静态方法,这个方法呢成为呢叫for name在这里边呢,去写上一个string形的,我们叫哎,Class的一个name。这样的一个方式,诶什么意思,你看啊,大的class点我们调这个叫for name for name这块呢,需要填写一个string的一个字符串了,哎,我这么着,哎,String类型的一个叫class name,我想加载谁呢?这呢就我们这个user,你要光写个user呢不行,因为呢,我们不同包下呢,可能有好多个userr呢。你得呢,把它这个路径呢写全了,那就意味着你要把这个包名呢也写上,然后这个user的话呢,我们所处的包呢,不就是这个吗。
21:06
好,把答CTRLCL一下,然后回过来,哎,粘过来点一下,这样才行。诶,我们把这个呢,通常称为呢,叫做全类名。哎,全类名。啊,也就是说呢,包含当前我们这个类的包名在内的这个类的一个完整的路径名啊,叫做全类名啊,这个呢,我们是这样粘的,还有一种方式呢,就是过来以后呢,大家双击选中点右键。这有一个呢,叫。呃,点这儿是吧,Copy reference是吧,诶点一下它,然后你再回过来,诶比如说这块呢,我们把这个呢给它就删掉了是吧,然后CTRLV一下。哎,这样的话呢,就直接呢粘贴过来它的一个权利名啊,然后呢,把我们这个字符串呢,我CTRLV就放到这儿了,他呢会报一个异常啊,那报异常呢,就给它抛出去吧。好,然后呢,这个方法调用完以后,我们再来一个al加个回车,是不是就也声明了一个大的class了。
22:01
哎,这个呢,它就诶不确定是什么了,就写成一个同位符了啊,这个写一个叫CLASS3,哎,咱们这块你也可以把这个呢,暂且咱们就先去掉啊,那么这个CLASS3我们看一看跟前面这个是不是一样啊。一样吗?哎,肯定一样嘛。只是我们通过不同的方式呢获取而已啊,哎,周琦。你看这种呢,就也是个出。那说明了它们三者呢,都是一样的,这个呢什么意思呢,就是我现在呢,就想主动的去加载这个路径下的这样的一个类,但是我一加载的时候发现它这个类已经在内存里了。那我就不再去加载了,所以这块你得到的就还是你现成的,也就是在最初的时候呢,加载过的这样的一个类了,所以呢,我们只是换了一个变量名而已。这里边儿呢,他们仨其实呢,都是指向的堆空间当中的最初的唯一的那样一个运营实类。啊,就是他,所以你看我这个名字起的呢,我也非常注意啊,我说呢,叫获取达达克拉斯的几种方式,没说呢,是创建大达拉斯实力的几种方式啊。
23:02
那创建呢,似乎呢,这个创建呢,跟这个创建呢,好像不是一个一样,其实呢,你只是通过不同的方式来获取到最初的那一个而已啊。好,那么这呢,就我们讲的这三种方式需要大家呢掌握,那除此之外的话呢,其实还有一种方式,那就是第四种要使用类的加载器的方式。啊,使用类的加载器的方式,那这块呢,就引入了这个叫类的加载器了。诶我们刚才呢,也提到内的加载器,就是说呢,咱们这个类呢,把它加载到内存当中了,谁加载的呢?诶类的加载器帮我们加载的,所以呢,你除了那个大的class呢,可以主动的去加载一个类之外呢。哎,我们这个内胆加热器呢,它也有这样的能力。啊,这呢,我们比如我们就使用一下,哎,这个叫class叫loader是吧。这个呢就叫类的加载器,首先呢,我们得获取一个具体的类的加载器了。啊,咱们这块呢,就先引入一个知识点,咱咱先用一下啊,我这儿呢叫get,一个叫system class啊获取了一个叫所谓的系统的加器,大家可能没什么概念啊,咱就先调一下,然后通过它呢,我主动的想去加载一个类,诶加载谁呢?诶我们就加载上面这样的一个user吧。
24:14
哎,我呢又把它也粘过来了啊,粘过来以后呢,这块返回给我们的,诶,也就是一个大的class的一个实例了。之后呢,就写成个四了啊好,这块我们再打印一下,看一下这CLASS1跟我们这个class这个四。哎,是不是同一个,哎,很显然呢,是不是也是啊。哎,这个呢,都得到是同一个啊。你看真看都是出OK,那么关于这个第四种这个方式呢,咱们呢,不要求大家掌握,哎,作为一个了解就可以了,为什么不要求掌握呢,倒不是说我们这个类的加载器呢,说没必要大家掌握了,主要原因是因为这里边儿这个三跟四啊,他们的使用场景呢,基本上是一样的。那我们知道这个全类名了,那我是不是就完全可以使用class,就没必要非得使用类的加载器了。
25:00
那他们是类似的是吧,那这里说我们这个一杠二呢,你看不一样,一个呢是直接调运营室类的一个静态属性,一个是有对象的话呢,那你就用这个。呃,然后呢,当然我们也可以选择三,三跟四的使用场景是一样,所以我们就没必要呢大家去掌握这个四了。好,前三种需要大家掌握,那么简单问一句,大家觉得这三种我们在反射这个层面来讲哈,你觉得哪种用的会多一些?啊。比如说第三种的。哪种?哎,其实呢,第三种用的要多一点。啊,为什么呢?因为第三种能够更好的体现动态性。啊,什么意思啊,你看我这呢,其实是一个string是吧。其实就是死锥形的一个变量了,哎,那具具体说呢,你说这个变量为代表的是哪一个类呢?哎,如果呢,我把它写成是一个方法的参数的话呢,你是不是完全看不出来呀。只有当真正传这个值的时候,你才知道呢,它加载的是谁是吧?
26:00
哎,如果我要不传这个参数,你根本不知道我加载的是谁啊。而对于上面这块,你看明确的是不是都写死了?EG呢,你看我这要写那个UC1,它立马编译是不是就报错了,因为根本就没有UC这个lay啊。所以呢,在编译的时候呢,它就校验这个类呢是谁了,而我们这个位置呢,我要写成右侧一,你哪知道呀。运营时候才知道靠不靠谱是吧,所以呢它呢,就更容易的去体现咱们这个动态性。啊,当然这块大家还是有点模糊,因为毕竟咱们刚开始讲啊,哎,只有呢,讲完之后呢,我们才能够去体会一下怎么叫动态性啊,当然这个词呢,我们翻来覆去的说得深入到你的这个。骨髓里边是吧,哎,只要说到反射了,第一个抛出来它的点,就是说我们要体现它的动态性,所以呢,我们反射这个框架里边才会大量的去使用它啊。好,这个呢,是咱们说的第一个知识点啊,获取它的一个实力的方式。那刚才呢,我们是提到了如何获取大的class实例的几种方式,诶这几种方式里边呢,前三种呢,是需要大家掌握的,这里边的话呢,我们是以这个类为例进行说明的啊大的class呢,指向的都是一个运行时的类了,那我们实际上在开发当中呢,我们说大的class呢,它指向的不一定是个类,它可能还是其他的这个结构,那我们下一个问题就是说大的class呢,都可以指向哪些具体的结构呢?
27:17
其实这块呢,结构就非常的多了,哎,我们来直接看一下这个课件了,哎课件里边的话呢,我们这块也有写。OK啊,这个呢,就是它可以呢,指向的结构,简而言之,所有的Java类型都可以呢,被我们这个大的class呢所指向,诶我们直接呢把它就粘过来了,就啊。上面这个呢,我们就直接呢,就叫比如说叫建代码了啊,大家去熟悉一下,好简单来看一下哪些类型呢,首先是这个class了,Class呢为代表的,比如说我们这个叫外部类啊,还有我们这个叫内部类这样一些场景,这都算叫内部类的一些成员了啊。啊,然后呢,这个接口也可以呢,被我们这个大的class所指向数组,也可以枚举注解基本数据类型YY,你看都可以啊。
28:04
诶这样的一些类型都可以好,那下边呢,我们就具体呢有一个代码了,哎,咱们把这个呢,直接呢粘过来啊,CTRLC回过来我们做一个说明。这个我们叫T1,哎,下面我们来一个这个T2啊。好,转过来来,我们看一看啊。这里边的话涉及到首先它为代表的是一个类,这呢为代表的是个接口,这个呢是一个数组,是一位数组,是二位数组都可以,这个呢是我们说的一个枚举。啊,这是一个枚举类了,然后这个呢是一个注解,这是基本属于类型,那这个VO是吧。哎,Y竟然也可以。所以这块呢,我们看到一个方法的返回值类型呢,叫word,你可以把word呢也看作是一种类型,只不过这种类型的话呢,就是我们里边呢,不一定非得要写这个return后边加一个具体的值了。诶,所以它呢,也可以看到是一个具体类型啊,然后呢,这个大的class本身呢也可以。啊,很神奇,他毕竟也是个类嘛。
29:00
是吧,也可以啊行,然后这块呢,我们把这个呢,先暂时的注意一下,上面这块呢,其实我们就运行一下也行。啊,也不会有什么效果了啊,只是说你看一下编译运行呢,都是可以通过的啊,然后下边这个呢,想说一个说明一个什么问题呢,就是说我们对于这个数组来讲啊,比如说我这是一个A数组,是一个in的类型的啊异位数组长度呢是十,这个B呢,也是in的型的异位数组,这个长度是100,它俩的话呢,如果获取这个大的class实力呢,我们说算不算相等,或者说怎么才算相等?这块提到了,说只要呢,元素的类型和维度是一样的,就认为是同一个class。你比如我们这俩呢,算是同一个吗?算对,因为呢,你看它们都是这个异位数组,而且都是int类型的,跟它这个长度呢没有关系啊。所以呢,这是我们这个C10和这个C11呢,我们要是去判断等等就是一个处。那当然了,你说我们这是一个int类型,这是一个string类型,那肯定就不是同一个class了。包括它这个维数哈,这呢是一个二维的,这呢是一个一维的,换句话说呢,我们不说本来也没有所谓的二维数组,就是你是个一维数组,你的元素呢,是这个是吧。
30:08
哎,然后我这个因位数呢,我的元素是int,所以咱俩呢,C4和这个C10C11也不是同一个class。OK啊行,这个呢,也还算是比较好理解,哎,那么关于我们这个大的class呢,基本上呢,我们也就说到这儿了,呃,大家呢,稍微的熟悉熟悉。
我来说两句