00:00
那接下来的话呢,咱们来看一下叫方法调用与返回指令,前面的话呢,咱们已经讲了这个如何创建类中对象的实例,以及呢,如何创建数组的实例,对吧?这个叫创建的指令,那我们也讲到了类或者是对象当中字段的访问,以及呢数组中元素的访问相关的一些指令,在这个结束之后呢,我们来看一下类中方法的调用,那方法这块呢,很多时候呢,都是非静态的方法,所以我们需要先有这个对象的创建才可以呢,接下来讲这个方法这个调用。这是其一,那其二的话呢,就是我们在这个实际开发当中啊,咱们说这个方法的调用的频率肯定比字段的调用是不是要多呀。当然字段这块呢,我们要直接调的话呢,一般咱们都是调静态的多一些是吧,你要说非静态的这些字段呢,咱们一般呢,是不是也都通过概率方法来进行一个访问和调用,对吧?所以这块呢,都归结为对于方法的一个调用,这个使用频率呢是很高的。那其实咱们在讲这个方法调用与反馈指令之前,咱们其实已经见到过相应的一些指令了,已经见到过相应的指令,只不过呢,咱们没有刻意的去说,比如说呢,咱们在这个new这里边的话呢,提到了一个new order,以及呢,我们这有一个print的一个方法,对吧?像这块呢,就是一个典型的一个案例,咱们这块来看一下关于这个set order ID这里边这个code。
01:19
那我们这块呢,是调用一下你这个order里边的一个叫这个类实力构造器方法,那我们这块呢,这不叫构造器嘛,以构造器为代表的叫类实力构造器方法,此时呢,就用了一个叫以默克special这样的一个指令。下边的话呢,system.out掉了一个printline的一个方法,这个方法的话呢,在我们这里对应的叫VO virtual,这个呢就是个printline方法对吧?所以呢,这里边儿已经出现了对于这个方法调用的这个指令了,只不过呢,我们当时呢,就是没有特意的去说,那下面的话呢,咱们来总结一下关于方法调用和返回这块的相应的操作。那关于方法调用这块呢,一共涉及到了有五个指令,那分别呢,就是对应的这五个,那下边呢,咱们就对这五个呢来进行一个说明。
02:04
那第一个的话呢,这叫invoke virtual,这个使用频率呢是最高的,但是这块呢,讲的话呢,它其实反而不太容易呢,说清楚,咱们先来说下边这几个例子,就是非下边这几个,它不就是对应的上边这个嘛,对吧,咱们先说下边这个,第二个呢,叫做VO interface interface呢对于大家来说呢,并不陌生,叫做接口,那我们调用接口什么意思啊,就是咱们调的就是接口当中的方法。调用接口中的方法,注意咱们这时候呢,主要是编译啊,你真正运行的时候呢,肯定是不是得提供接口具体的实现类的对象呀,那肯定这个实现类也要重写这个方法结构中的方法,咱们叫实现结构中方法也行,对吧,那你肯定是调的是你这个具体的子类,呃,这个实现类中的重写的那个方法了。那但是呢,我们声明的时候呢,如果你是比如我们这一个接口呢,假设啊是AA,然后咱们叫个小A,然后右边呢,就是你具体new的一个时间类的一个对象了,然后通过这个小A点咱们去调的声明的时候呢,这是一个接口中的方法,那么它对应的就是叫invoke interface。
03:08
就是这个结构好比较好理解,下面那个叫VO special special呢就是一个特殊处理的这种方法,注意这是个实例方法了,那它呢,是包括哪些呢?提到了这样的三种情况,有实例初始化方法,也就是咱们所谓的那个类实例构造器方法。就是实例初始化方法,就因类的方法,就这个意思,以及呢叫私有方法,还有呢叫负类的方法。大家有没有发现呢?这三种方法呢,有一个共同的特征,就是他们不存在方法的重写。你看这块我重点强调了不存在方法的重写,比如说我们想调用指定的构造器,那构造器本身就不可能重写,对吧?所以我们想调哪个实例初始化方法,那是哪个就是哪一个,所以非常明确的,那私有方法呢,本身也不可能实现重写嘛,对吧,私有方法那负类方法呢。
04:00
负类方法当家,你想我这是一个子类,它呢继承了这个负类,这个负类呢,假设还有个负类,我现在呢,通过这个类的实例去调一个super点负类一个方法,那就掉它里的了,它要有那就直接掉它,这就是确定的,对吧?那如果它要没有的话呢,我们就接着再去它的复类中去找,看看这块有没有,如果有这就是确定的了,所以呢,不会存在说你你调的某个方法,编译的时候是这个类中的啊,运行时候又是它重启的子类中的,不可能的,那我们是从下往上找负类的,所以也是确定的。啊,所以这些呢,我们都称为呢,叫做special,就是非重启的那种场景,那对于这种确定性的方法呢,咱们称为呢,叫静态类型绑定。叫做静态类型绑定,就不会在运行的时候呢,进行一个叫动态开发或者动态分派,这个咱们在上篇的时候呢,讲方法这块呢,提到过这几个指令,其实。提到过这些指令,只不过我没有详细的给大家从最己码的角度呢详细的去解读啊,在下边呢,叫invo static,顾名思义就是调类当中的静态方法。
05:04
或者叫类方法,这呢也是一个静态绑定,因为呢,静态方法本身也不存在方法的重写,所以呢,这也是一个静态绑定的。所以通过尤其是咱们下边这两个静态绑定,这两个说完之后呢,咱们回过来说一下叫invoke virtual。那这个virtual呢,它主要呢,就是一个叫动态的分派了,或者叫动态的这种绑定,那主要呢情况就针对于咱们多态场景下方法的重写。方法的重写,那当然你想咱们呢,刚才调这个system.printline的时候呢,我们完全有可能是不是说你print stream这样一个,这个叫打印流的一个具体的子类的一个对象,假设呢,呃,子类的一个对象把这个方法呢给重写过了,那我们这呢,可能真的就是重写的人间里边那个方法了,对吧。那所以说这里边呢,我们这普纳方法是有可能被重写的,那既然你可能会被重写,那我们编译的时候呢,可能是一个声明的父类类型,真正运行的时候就是子类类型,这就是一种叫动态分态,那这种场景呢,我们就称为呢叫work watch。
06:08
或者大家呢,目前啊,就是咱们说非这几种呢,我们主要见到的其实就是invo。就这个这样的,大家去体会一下,那当然最后这块呢,说你这不还有一个吗,叫银和dynamic是吧,这个呢就是动态绑定,那针对呢,是咱们JDK1.7的时候呢,咱们为了体现Java语言这种动态性呢,提到这种动态绑定的一个特征,那这里边呢,咱们就不具体的关于这个和dynamic呢来进行讲解了,因为这个呢,一两句话呢,咱们还这个解释不清楚啊,这个场景呢,我们给大家得这个造出来,然后给大家呢去具体的细节去讲解,这块咱们就先暂时过掉它,如果大家呢,有兴趣呢,去了解这个个dynamic,咱们后续呢,可以给大家再补一个这样的一个视频,或者呢,大家呢,可以在网上去搜索相关一些帖子,这个书籍是吧,学习一下也OK啊,咱们这里边主要带着大家呢,熟悉的就是上边的这四个。OK,那咱们这块呢,来看一下这个具体的代码。
07:00
这块咱们找到method invo return test行啊,找到这了,那这里边呢,我们先来说一下这个VO special special,回忆一下咱们刚才涉及到哪些情况啊,这个一个呢,就是是不是叫类实力构造器方法呀。看这个叫情况一到方法对吧,这个呢主要指的就是咱们这个in这个方法,这个new,一个date new一个thread,这呢都是涉及到叫in构造系方法的情况,以及呢,我们说这个呢叫情况二,这呢是我们调用负类的方法,情况三调用当前类中这个叫私有方法。行,那这几个呢,都是叫invo special,那咱们把当前这个代码呢,给它做一个编译,呃,然后这里边咱们再做一个查看。稍等。嗯,来这块呢,我们做一个查看。打开找一下,我们这叫VO1对吧,来看一下这个里边的执行,那我们这里边关于这个new data,你看invo special指是data的一个in列的方法,然后在下边呢,In special是thad里的in列的这个方法,下边呢副类的方法,负类的这个当前咱们这个类是它它的副类呢是object啊,调到这个to资人方法,还有这个私有方法啊,也是以莫克special。
08:25
没问题,思维方法是下边这块定义的。能行吧,OK啊,诶那问大家一句,你说我要把它呢去掉,或者说呢,你看我改成一个public,那这时候呢,变成什么了呢。能想到吧,肯定不一样了,对吧。好,这块你看我做一个刷新。刷新完以后呢,你看我们这时候再看是不是就变成叫了,因为不是一个私有的方法呢,我们这个方法就有可能是不是被当前这个类的子类呢所重写对吧?哎,所以呢,这就是一个龌龊了啊,这个要小心一点,只有针对于私有的这种不能重写的啊。
09:00
才会可能出现这个叫invo virtual,呃,Work这个special,所以这里边我们把它称为呢叫静态分派。哎,这个叫静态分派,行,然后接着我们再往下看,叫invo static啊就是静态结构,我这儿呢写了一个静态方法,然后我们在这呢进行了一个调用,叫invo,那这个method static in2里边进行涉及到的,然后这块呢,咱们打开看一下invo to。那这个呢,我们是不是就叫invoke static呀。OK,没有问题对吧,啊,因为static,那有同学可能会问,诶那老师这块呢,既是一个static,我又把它声明成是一个private,那那这这这怎么解释啊,那我把它看成是一个私有的呢,还是看成是一个静态的呢。来,我们刷新一下。好,这时候大家会发现是不是还是个静态的呀,所以这块呢,主要我们提到这个静态结构呢,是通过当前类来进行调用的,所以呢,优先考虑这个是static。
10:00
啊,稍微注意一下这个问题。对吧,那没问题啊,行,这个呢,你改过来也可以,不改也没关系,那这块关于静态方法呢,我们说本身也不存在这个重写嘛,所以他也是在我们编译的时候呢,其实就完全确定下来的就是这个方法了,所以这块呢,我们也称为呢,叫做静态分态。哎,这也叫做静态分态行,然后再往下的话呢,涉及到关于这个interface,我们称为呢叫接口中的一个方法的调用行,大家你看我们这个例子,我这呢有一个thread,这呢又涉及到叫special,对吧?那关于in的方法的调用,然后接下来的话呢,我们把这个T1,你注意啊,我这个T1的话呢,不是这样写的,你像咱们下边这个操作移完之后呢,直接通过T1去调这个run,那此时这个run的话呢,有可能被thread的子类重写。对吧,那有可能被它的或者这块你看我写成个no也行,要不大家说如果没重写啊,那我这写个no,就是我具体没有赋值呢啊,然后这是我们调这个run的时候呢,咱别去运行,你说这控制帧了,这个咱们真正运行的时候才知道控制帧,现在呢,咱们看这个指令调用的话呢,子类呢是有可能重写的,那这时候我们去看这个问题,咱先看下这里共有个四。
11:13
它呢就是一个叫invoke virtual,上边这个invo special是调这个构造器方法invo virtual对吧,这是没问题的,但是呢,我们上边这个呢,我把这个T啊给它强转成是一个reable类型,那此时我们点下这个按住CTRL键点那个run是不是就点到我们这个reable这个接口里了,那就认为呢,我们在编译的时候呢,调的是接口中的这个结构,所以呢,此时展示的呢,就是look interface。啊,Interface,那下边这个comparable呢,也同样的道理,那我们带掉了compar to1按住CTRL键,然后这时候我们进来的是不是就comparable里边这个抽象方法了,那这时候呢,我们来看的话呢,这也是一个worker interface。那调查这里边的一个compared to这个方法对吧?OK,没问题,行,这呢我们就提到接口中那个方法调用这里边我们提到叫in work。
12:03
那么这个完事之后呢,大家再想个事儿,咱们在讲这个JDK8的时候呢,提到过接口当中是不是还可以去定义叫static,叫静态方法和默认方法呀。呃,顺带说到这儿了,那这时候咱们就顺带呢再说一下,那关于这个静态方法和默认方法的调用,呃,那这时候他们是叫evoke interface吗?还是叫EVO virtual呢?对吧?哎,还是invoke static呢?这个咱们可以再额外的给大家举个例子啊,比如我这块再写一个这关于咱们这个啊,叫interface。Method的一个测试。啊,这个在咱们这儿写一下,相当是一个补充,关于这个方法调用。指定的一个补充说明,好这块呢,我们主要来看一下这个接口中的这个情况。我这呢,声明一个接口。这个接口呢,比如我就叫A了。
13:02
在这里边我们说G8当中,咱们可以去定义静态的方法。我就要MESSAGE1,具体方法起我就不写了,还可以呢,去定义这种叫默认方法。行,那这呢我就定义了两个方法,接下来我们去提供当前这个接口的一个具体的实现类,比如我们叫这个BB去implement一下这个A。没问题对吧,那实现以后呢,我们说当前你这个A中也没有这个抽样方法,所以我们这呢,也没有进行一个方法的这个实现了,那没关系,然后在这个测试里边呢,那方法当中,咱们声明成是一个接口类型的,具体new的话呢,我可以去new一个具体的这个实现类的对象,对吧?然后呢,我通过这个AA呢去点注意,一方面呢,我们去点这个me,二另外一方面呢,我通过A,注意是不可以去调这个static的方法的,静态的方法呢,只能通过咱们这个类啊,不是通过这个接口呢来进行这个调用。
14:07
那我们现在主要关心的就是这两个结构,它对应的这个是什么呢?哎,我们给它做一个编译。好了对吧,那这块呢,我们再进行一个view。打开咱们看一下这个,嗯,注意是咱们当前的看下这个类型信息。对吧,哎,当年这个测试里边这个没方法。找这个没方法。看这行来分析,那这块new,然后和special,这呢是因为叫咱们这个BB的这个构造类实力构造器方法了,所以这个能理解,关键就是我们看下边。当我们调这个METHOD2的时候,你看METHOD2这块我们调的是不是叫invo还是叫interface啊。发现了对吧,还是interface,那下边这个METHOD1呢,注意变了,METHOD1呢,咱们这是一个静态的,所以呢这呢显示的就是invoke static。
15:03
那这两个大家稍微注意一下这个特点。OK吧,行,那这样的话呢,咱们把这个这个方法调用这块呢,主要的这四个呢,咱们就说清楚了,重点需要大家关注呢,就是叫in virtual,在多态的场景下呢,我们说这个子类可以去重写,那就是一个叫虚方法嘛,动态分派的一个场景对吧,就是动派分派,相较于咱们上面的这个调用这个静态结构啊,调用这个special啊,这都是叫静态分派的,大家熟悉一下。
我来说两句