00:00
大家好,我是海波老师,我们继续来讲Java语法中的反射啊,那这里呢,我们讲一下Java的字解码文件啊,咱们前面提到了我们这里的class对象啊,其实就对应的我们那个Java中的什么自解码文件,而所谓的自解码文件呢,就是咱们使用Java c指令啊编译的那个源码文件后的那个class文件,咱们点击我们的file,然后呢,我们找到项目的一个结构化的一个视图点一下,点击以后大家可以看到我们这边有个叫comp output,这个路径是什么意思,它就是我们的idea把咱们的Java源码程序编译之后,那个class文件所存储的目录,那这个目录呢,就在咱们项目当中有一个叫out,你会发现我们的alt的文件目录啊,跟这个SRRC的文件目录呢,它的颜色不太一样,我们这个SRRC呢是源码目录,所以呢它是一个蓝色啊,而我们的这个out呢,它是一个输出目录,所以呢,它是一个我们的橘黄色,那咱们打开,打开以后你会发现我们当前的这个out目录呢,其实里面的结构呢,跟我们这里的结。
01:00
结构啊,大同小异,也是分我们的一些包对不对,那么其中我们之前打开里面也会有一些什么child u,什么什么reflect,对不对,没有任何问题,那好我们双击一下,我们双击以后,诶,你会发现在咱们当前的这个地方有两个文件,只不过呢,它的扩展名不一样,一个叫做Java,一个叫做class,对吧?诶这个class呢,我们就叫自解码文件。哎哟,老师不对吧,你这不还是我们的代码文件吗?对不对,里面不全都是我们的代码吗?哎,其实不是,你有没有注意到我们上面的这句话,上面的这句话它表什么含义呢?它就告诉你了,我们这里的文件内容啊,是通过我们JAVA17反编译字解码得到的内容,我们这里的decomeld啊,它就是反编译的意思,那么这里的61呀,它指的就是我们Java的版本,咱们JAVA17就这意思,如果这样写上是52的话,那么它就是JAVA8了啊,咱们这里是我们的61,它就是JAVA17啊,因为字解码文件的内容啊,你是看不懂的,所以idea为了你能看懂啊,它贴心的帮你把这个文件反编译了,所以说你打开之后,你看到的是我们反编译它的一个文件内容,你有没有发现咱们这个里面根本就没有构造方法,但是你会发现它里面是不是就有了,对不对,诶就是这个道理啊,你也可能会不信,我怎么会连个文件都看不懂呢?来,咱们把这个文件啊,咱们在资源管理器里面我们打开。
02:23
打开以后,我们这里呢,我们看一看,它里面就全都是一些我们的class文件,都是我们编译后的那个自解码文件,我们把这个文件呢,我们打开一下,我们点一下打开,打开以后大家看一下,我们能看懂吗?哎,我相信啊,咱们有的是不是也能够大概看一看是吧,里面都是一些字母呀,数字之类的,里面什么树豪啊,什么Java呀,浪啊,Object,好像它也能看懂吧,对不对,但是啊,我们整体合在一块,咱们不知道是个什么东西,为什么呢?其实这个文件呢,它是用16进制进行编码的,所以呢,我们需要采用16进制的方式,我们查看一下,我点一下,里面呢,都是一些我的数字和我们的字母,对不对,虽然说我们也看不懂,但是你会发现呢,我们文件最开始的几个字母非常有意思,它叫cave baby啊,咖啡宝贝对吧?那干什么用的呢?其实啊,就是Java专门用于区分自解码文件和其他格式文件的,诶,我们这个就是一种标记啊,它标记我们当前的文件,我们就是一个自解码文件,我们一般把它呀称之为叫。
03:24
Magic number,咱们叫魔术啊,后面的这个数字呢,它表示的是Java的版本,那么这里的3D呢,它就表示的是我们的62的意思,也就是JAVA17啊,这里咱们说一下就可以了啊,那么这些全都是16进制的数据,我也看不懂怎么办?没事儿,咱们Java提供了一个命令,可以让咱们查看自解码的内容,所以呢,我们在这个位置,我们打开,我们在这个地址栏上,我们写上CMD,打开一个命令行的黑窗口,然后呢,我写上一个叫javap,这个javap呢,是我们Java所提供的一个反编译的指令,然后呢,我写上一个杠V,我再写上咱们刚才的这个操作,所以呢,我我这样吧,我们把这个叫做跳的吧,把它拿过来。
04:07
好了,我回车,回车以后大家会发现在我们命令行窗口当中会打印一大部分的内容,对不对,这个就是我们能够看得懂的字解码文件的内容,大家可以看到啊,就是它了,那么这些内容当中啊,它包含了这个类被Java逊机执行的时候的所有信息,比方说它里面就包含了我们的类名,以及它附类的名称,还有呢,我们的接口,还有我的属性,还有我们的方法,对不对,还有什么常量词啦,很多很多啊,那么既然这个类的信息全部都在这个字解码文件当中,而我们Java虚拟机在执行的时候会读取这个文件,那咱们能不能获取到我们这些信息呢?比方说我们的类名啊,我们的这个什么副类啊,还有什么接口啊,能不能获取到呢?我们说是没有问题的,那之前咱们不是已经在程序当中获取到了咱们的那个class对象吗?这个class对象就是把那个自解码文件当成了一个对象,那么我们通过它就能够得到咱们那个文件中的内容,好了,这个呢,咱们一个一个给大家看一看啊,那么首先呢,我们获取那些我们的。
05:07
内容啊,它可能会出现异常,所以呢,我在这个地方呢,我先提前我们throws,我们抛出咱们的异常啊好了,抛出异常之后,我们这里呢,写上它,那么我们就按照我们这个打开的内容呢,首先我们看看第一个呢,它这边有一个类名叫list class吗?诶,所以我们就写上它获取。啊,获取我们的类的名称,你当前的这个class就是字节码啊,它里面就有类的名称啊,所以我们拷贝,拷贝以后呢,我们点它里面有一个方法,这个方法的名字呢,叫get name。这个我一看就简单了,对不对,这个一看就是获取名称嘛,对不对,但是除了这个以外,还有一个咱们先打印一下,然后呢,我们再来把这个去掉。去掉以后我们点一下叫get,有个叫simple name。诶,这什么意思啊,很奇怪,我们要想获取名称,怎么有两个名称呢?给大家解释一下,咱们的这个名称呢,它就是获取。
06:05
我们类的名称,比方说你的类叫child,你的类叫U,诶我们这里就可以获取到我的child,我的U,但是呢,我们说了咱们的类啊是有包名的,对不对?如果你想获取它的一个完整名称的话,包含它的包名的话,就应该用这个方法了,这里呢,是获取啊类的完整名称,那么括号啊,咱们叫包含我们的包名。好了,咱们可以验证一下,咱们试一试运行。运行以后,大家可以看到我们这里呢,是我们的带了包名的这个类,而这个呢,是不包含的,对吧?所以这个可以自行选择来使用不同的方法,诶老师呀,那既然这个包名我们有的话,那咱们能不能获取到呢?其实也可以大家看一下来,我们把这个呢,我们去掉,去掉以后呢,我们这里有一个叫package啊,咱们叫package name,其实也有一个方法呢,是获取一个包的一个对象,那咱们这里先不管他吧,咱们这里把这个包的名称咱们给他过来。
07:02
所以呢,获取啊,咱们叫做我们叫类的包的名称。好了,我们这里呢,我们点击右键,我们再来看一看,这个应该没问题啊,咱们的包的名称就叫CHAPTER10对吧,就是这个意思,好了,那么类的名称我们已经获取到了,那么我们这里看一下,他还有super class呢,就是你的副类啊。那么大家可以看到我们这个里面的对象啊,就叫child,那么child的话,它里面不就应该有负类吗?所以呢,我们这里写上它来,写上todo叫获取类的负类,我们这里呢,把这个对象呢,我们拿过来,拿过来以后呢,我们点一下,我们叫get super class,这个super class呢,其实很简单,顾名思义就是获取我的负类嘛,对不对,所以我们点一下诶VR回车补全,它补全以后大家可以看到我就得到了一个类对象,你把那个负类的那个类对象就取到了,你想想吧,咱们这里呢,是我们的这个叫做child,那它的负类就是U的,我等同于把那个U的对象取到了,对不对?所以呢,咱们这里直接打印一下来,然后呢,把我们的super class呢,我们放到这里来,我们运行一下,运行以后你会发现我们这里得到的就是那个U,刚才那个叫child对不对,哎,就是这个意思啊。
08:15
那么负类有了以后,那么我们这里啊,有一个叫interface,哎,咱们前面讲过了啊,咱们的这个类可以实现接口对吧?诶,所以我们写上它要获取啊,获取我们类的接口,但是你要记住啊,咱们这个接口啊,它会实现很多的接口,对不对,所以呢,我们拷贝,拷贝过来以后,点咱们叫get,有个叫interface,这个interface加了个S,它表示多个的意思啊,咱们的一个类可以实现很多接口,那么它返回的是什么呢?它返回的就是我们的一个接口的一个数组,你看咱们的数组对不对,为什么呢?多个嘛。但是呢,咱们这个,嗯,咱们的child呀,没有实现任何的接口,所以呢,我们打印一下啊,咱们打印一下,打印以后这个interface呀,它里面的这个长度啊,应该为零对吗?这个肯定的啊,所以运行一下。
09:06
咱们这里的长度呢,它不就是零嘛,诶这个我相信大家都能够明白啊,这个比较简单了,好了,接下来我们来往下看,我们下面呢是我们的属性和方法,咱们这里呢,没有属性,有一个方法,那肯定啊,咱们这个child里面没有属性,但是有一个方法对不对,没问题啊,所以呢,我们写上它,咱们叫做它嘟do,咱们叫获取啊类的属性,还有一个叫获取类的方法,那么这个属性我们该怎么获取呢?我们还是拿到这个类对象来拷贝,拷贝以后点跟属性相关的方法其实还是比较多的,大家可以看到我们这里有四个方法,那么这里面有个叫get fair的啊,还有一个咱们去掉,咱们写上它,咱们叫declared啊,咱们叫declared,咱们叫field,诶,放过来。这两个方法呀,其实好理解,为什么呢?因为看这个名字呀,就是获取我们的某一个属性的意思,所以呢,里面应该传一个我们属性的名称,那咱们叉叉叉叉叉我随便写的啊,咱们随便写的,我们这没有嘛,我随便写,写完了以后大家可以看到我们这两个啊,咱们来返回一下,我们叫做点VR回车,回车以后我现在呢,就写上一个F,然后呢,我这也写上一个他,诶回车。
10:18
好了,写完了以后大家可以看到,诶老师呀,你这两个方法不都返回了一个属性吗?那这样的话我们的属性是个对象,那这有啥区别呢?哎,我告诉大家有区别,区别就在于我们通过一个名称从这个类里面得到了一个属性,但是。我们的属性是有访问权限的。什么意思?我们的这个方法呀,它获取的是什么呢?它是public访问权限的属性,也就意味着如果你的属性是我们的公共的访问权限,我这个方法就能取到。但是如果你是什么私有的呀,什么受保护的,我们这就取不到了,那怎么办,我们就得用它了,所以呢,这个咱们写上它啊,咱们叫做什么呢?权啊,所有咱们叫所有,嗯,我们的权限。
11:04
所以啊,这两个方法它不太一样啊,诶老师呀,那我不想通过名称来获取数据,我想把所有的属性拿到,可不可以呢?当然可以了,我们刚才呢,还可以用这个方法来拷贝,拷贝以后点一下我们就get我们field这里面有个SS。这个呢,就会把所有的属性呢,全都拿到,形成一个属性对象的一个数组,这个field呢,就是属性对象的意思,那么中国号呢,就是个数组了,对不对,我这没有嘛,你这没有的话,它的长度不就是零嘛,对不对,就是这个意思啊,这个咱们先不管它,那除了这个以外,其实还有一个来咱们写上点,咱们叫get declared啊,我们叫field,哎,就是它,诶大家会发现是不是感觉跟上面很像。我们这个地方呀,咱们来写上它,咱们叫做点,我们叫VR回车,你会发现差不多啊,诶其实它们的含义是一样的,我们的这个方法呢,它同样也是获取所有的公共访问权限的,什么我们的这个属性,而我们下面的这个declare的叫声明嘛,我获取声明的属性,那么所有的属性我们都是声明过的,所以它的权限就比较丰富,比较多,对吧?诶,这是我们的类的属性。
12:15
那好了,属性有了,咱们接着下来看方法,那么这个方法呢,我们同样道理也是这样做的,我们的类的对象我们点我们叫get method,诶有没有发现同学们这个method,诶跟这个很像啊,你叫get field获取属性我叫get method,那不就是获取方法吗?诶,我们的方法对象就叫method,我们这里啊也给它一个名称,哎,写上它,写完了以后跟这个概念是一样的。我们前面的这个属性啊,我们可以根据叉叉叉叉叉来获取,我们这里呢,也可以根据我们的叉叉叉来获取它方法的这个对象,记住啊,我只是告诉大家语法是这样的,我可没说它里面有这个东西啊,那比方说这里叫TEST2,那我这不就应该写上一个TEST2嘛,对吧?你别误会了,我这个叉叉叉是随便写的啊。
13:02
好了,那你这么写完了以后,咱们再来一个把这个我们的类的对象拷贝,拷贝以后呢,我们点我们叫get我们的什么method a不对,Get我们的declared method,咱们找一下咱们在这。搞完了以后,我们也写个叉叉叉,我们来,我们写了点VR回车,回车以后大家有没有发现很像啊,都是通过名称来取得我们的方法对象吧,但是不一样哪不一样,看到它没有。看到这个叫declared了吗?诶,你看到它的话是不是跟这就一样了,什么意思?我们同样道理,我的这个也是获取公共的方法吧,而我下面呢,也是所有权限的方法,我们要通过它来访问,诶这个你能明白就可以了,咱们就不再说了,那同样道理,你想获取所有的方法,那么我们也会有这样的东西,所以呢,咱们写上一下,咱们叫我们的对象啊类的对象我们点一下叫做get,我们叫method,这里加上个S表示多的意思,回车,回车以后得到的一个method对象的一个速度。那么同样道理,我们把这个呢,来,我们想它点一下叫get,我们的declared method。
14:09
把这个呢,我们的master在这啊,然后呢,我们点一下VR回车,诶这样的话我们的方法也都有了,同样道理,它是公共的,而它呢是我们所有权限,对吧?哎,所以啊,我们的属性和方法你会发现非常的类似啊,那么除了我们刚才所说的方法以外,我们的类对象中有一个特殊的方法什么呢?我们叫构造方法。所以啊,我们这里写上它,我们叫构造方法,什么叫构造方法呀,就是用来创建对象的方法,对不对,那这个时候我们来把这个类对象拿过来,然后呢,我们点一下它有什么呢?有一个这个东西叫做我们的constructor。这个我们的方法其实就是构造方法,它返回点一下VR回车,这个就叫构造方法对象,诶我们就可以通过它来构造对象老师呀,那咱们的这个类当中可能会有很多的构造方法,对不对?诶我们这里也是一样的,所以我们拷贝,拷贝以后呢,我们这里来啊,咱们点一下咱们叫get,我们的constructor,你会发现它里面也可以返回咱们的数组啊,没问题,诶,所以这个大家明白就可以了,当然了,还有我们点一下叫get,我们这边也会有那个叫做get declared啊,我们的constructor也是一样的啊,所以本质上这几个都大同小异,你把这个含义记住了,每一个都差不多啊,这个呢,咱们就不再一个一个给大家演示了,大家知道怎么回事就行了。
15:32
诶,那老师啊,咱们前面一直在强调权限,那我能不能得到权限呢?我告诉大家也可以,所以呢,我们想要突突啊,获取我们的权限。啊,比方说我的方法权限,我的属性权限,我的类的权限,我都可以获取到,所以啊,咱们把咱们的这个对象拷贝过来,拷贝过来以后点它会有一个什么呢?叫做get,咱们叫mods。诶,这个Mo fair,它表示的就是我的权限,诶放到这边啊,所以啊,这个权限其实我们叫权限也行啊,咱们叫修饰符。
16:06
什么叫修饰符啊,什么公共的,什么static,什么final,对不对,这都叫修饰符,哎,老师不对呀,你public是修饰符,你的static是修饰符,你的那个final也是修饰符,那为什么你返回的是一个值呀,对不对?这里给大家解释一下咱们Java中这个修饰符啊,它采用的是什么?哎,我们的数字也就意味着我们这个返回的结果,它其实融合了多个我们的修饰符,也就意味着我们的修饰符啊,咱们说一下咱们的多个修饰符啊,修饰符它会融合啊成我们的一个值,一个int值。也就意味着这一个值就能表示多个修饰符,哎,老师,那这是为什么呀,这个采用的就是我们的未运算了啊,未运算了咱们就是什么呢或的运算啊,这是一种用的一种货的运算。诶老师,那你这个我怎么判断,你到底是不是什么修饰符呢,比方说你到底是不是公共的呢?诶给大家解释一下,我们这里啊,其实有专门的类,我们可以操作一下,比方说我们把这个叫Mo fires,我们拿过来,拿过来以后呢,我们点一下啊,咱们点一下嗯。
17:15
把这个呢,我们去,诶把这个地方去掉。倒一下,倒完以后呢,放得过来,然后呢,我们写上它,我们点一下叫is,大家有没有发现我们这个里面会有很多的判断,这个判断就是判断你有什么样的修饰符,比方说你是不是抽象的,你是不是final的,你是不是我们私有的,你是不是公共的全都有,诶你这么一点点击之后,你把这个东西你放进去就行了。你放进去以后它会返回啊点一下。诶,返回一个布尔类型的,你不就知道它到的修饰符,它的访问权限到底是什么了吗?对不对,你看这不就有吗?诶,所以啊,这就是我们获取修饰符的一种方式啊好了,这个呢,就给大家介绍一下,我们把我们类对象当中的一些常见的东西,包括我们自解码当中有的一些东西呢,这里给大家介绍一下就可以了。
我来说两句