00:00
大家好,我是海波老师,接下来我们来继续讲解Java语法中的方法参数,我们之前给大家讲过了,所谓的方法参数呢,就是在方法声明的时候,小括号里面写上一个参数,这个参数呢是参数类型和参数名称,当然了,我们的参数列表嘛,它里的参数可以有多个,对吧?那么多个参数用逗号隔开,那么这里的参数列表呢,我们要考虑参数的个数顺序和它的类型,对吧?但是呢,在相同含义的不确定参数的时候呢,我们可以考虑一种特殊的参数,我们叫可变参数,这个咱们之前是给大家介绍过的,对不对?我们这里不再给大家去回顾这些内容了,我们主要给大家想讲讲参数的使用问题,所以我们这里关掉,关掉以后我们来拷贝,拷贝后我写上个下划线一。好了,然后呢,点击OK,点击完成以后,把这个改成下划线一好,把里面的东西我就全去掉。去掉了以后呢,我们现在呢,给大家去写一个小的一个代码,小的例子啊,咱们来我就把这个方法呢,我是原封不动给它拷贝过来,拷贝完成以后,我这里呢,给它改成一个叫test,好把这里的参数呢,我改成叫int,非常简单,我当前的这个方法声明的时候呢,就给了它一个int,一个I的值,然后呢,我的里面呢,写上I,它等于I加上十,就这么简单。
01:18
诶,那这个方法怎么去用呢?咱们这么用,我先写上一个int I,它等于十,然后呢,我去调用这个方法叫test,我们写上一个I就可以了,好了,那写完了以后,我就想打印我当前的这个I的值,其实啊,大家会发现这个逻辑其实是非常简单的,为什么这么说呢?因为啊,我声明了一个变量,把十复制给它,那么好,我的I就是十了,然后呢,我调这个方法之后,把I的值呢传到了这个参数当中,所以这个I呢,就是十了,十再加十不就是20了吗?20再重新复制给I的话,那么I不就变成20了,所以我打印咱们的I不就应该是20吗?所以这个逻辑非常清晰,所以呢,我现在运行一下看结果,大家会发现我们的结果好像不太对诶。
02:05
刚才分析的没问题啊,刚才的分析结果不应该是20吗?怎么这里结果变成了十呢?那么我们接下来就给大家讲一下参数在底层到底是怎么去实现它的传递的,那么怎么传递的呀?咱们看这个图来,首先啊,咱们讲过了,我们方法在执行的时候啊,其实它是在我们的站内之中去完成的,所以我们这里把它拷贝一下。拷贝完成以后,我们往下来,诶往下走,往下走以后,那么咱们说一下我们的Java虚拟机在执行任意一个方法的时候,它都会在这个蓝色的方块里面创建一块内存,这块内存的名字我们称之为叫战争,记住任何一个方法都会创建,所以我们说一下它叫做战争。所谓的战争呢,就是一块内存空间,那么里面存什么东西呢?就存这个方法,内部的一些参数啊,变量啊,一些执行逻辑啊,就存这些东西了,那好,既然他存的是这些东西的话,那么就意味着我的CPU呢,就会执行我们的它,所以来拿过来。
03:04
啊,我们写上它,我们叫CPU啊好了,那么我们CPU呢,就会执行里面的逻辑嘛,这里我们给它一个红色来代表一下好了,那我的箭头呢,就会指向这个位置,诶可以了,好,那我们说完了以后,那么有问题了,什么问题呢?如果我们这个黄色的战争当中,他执行的另外一个方法怎么办?我不说了吗?咱们一个方法,它执行的时候,Java虚拟机会往这个蓝色的站里面创建一个我们的战争,一个我们的小黄色的方块,但是如果在黄色方块里面我又调用了方法怎么办?记住同学们,我们要保证CPU的这个箭头不变,就意味着它的指令位置不变,那么我的战帧就会被往下压。什么意思呢?就意味着我们会有个新的战争出来,我这里用绿色来表示,就意味着这个之前的黄色战争会往下压,就是这样,哎,那这样的话,一个新的战争就出来了,那老师那如果再来一个方法调用呢,记住了,它还会往下压,诶往下压,所谓的往下压呢,就是往下放啊,诶所以说我们往下挪,挪完以后往下挪,然后呢,我们这里呢,拷贝拷背以后放过来,那这里呢,我们给它一个我们的这个颜色吧,好了。
04:12
同学们,CPU的箭头没有变,它就会执行我当前的这个战争中的逻辑,诶老师啊,那如果方法执行完了怎么办?记住如果我们的方法执行完的话,我们的加入虚拟机会把这个战争从当前的这个蓝色的方块里面给它弹出去,就意味着把它弹走啊,把它弹走弹到这边吧,弹到这边以后我用灰色来表示一下什么意思,表示不再使用了,记住表示的是不再使用了,所以我的箭头呢,就把它弹出去了啊,这个意思,我这个表示的箭头呢,就是把它弹走的意思。那你把它弹走的话,可是你的CPU没变呢,所以怎么办?他就会往上挪,诶,再回来,同学们能不能明白这个意思,就意味着我的前面这个战争被弹出去了,那么他们两个就会往上挪,同样道理,这个战争如果执行完的话,他也会被弹出去,懂我的意思吗?他也会被弹出去,标灰不再使用了,所以我的箭头呢,它也被弹出去了,好,它弹出去以后,他又回来了。
05:10
同学们懂我的意思吗?好,如果他也执行完了,它也一样会弹出去,诶,所以你会发现这样的话比较简单,否则呀,我的CPU的这个指令箭头啊,就来回跳就比较麻烦,而我们这就不来回跳了,保持不变,我们只要占内存当中的这个小方块帧,它不断的变就完了,所以咱们这里啊,会有一个概念啊,什么概念呢,叫做我们的来咱们叫压战。好鸭蛋的概念,还有一个叫谈战的概念,所以来说一下。什么叫做压战,什么叫做谈战呢?非常简单,所谓的压战和谈战,说的就是我们当前的这个我们的战争往里往下压,对吧,你的战争往下压,这就叫压战了,你看他就往下压了嘛,他如果往下压的话,我的箭头来咱们复制一下,复制过来放过来啊,他就往下压了,不就是这个意思吗?什么叫谈战呢?当你执行完往后弹呀,诶,这就是我们谈战的概念,所以呢,我这里写上它啊,在这写上咱们叫做谈战,诶好了,那这个呢,我们就称之为叫做压站。
06:13
同学们,这个能不能明白呀,诶来,咱们叫压善啊,好了,行了,写完了以后,这是一个我们方法执行的基本原理了,那接下来咱们就要说参数的问题了,咱们回过头来再来复制一下,好复制复制以后咱们往下挪啊,往下挪来往挪,挪完了以后我们把这个去掉,把它也去掉,把它也去掉,行了,那么去掉了以后,咱们回过头来看这个代码,这个时候大家会发现我们有一个闷方法,对不对,那么这个闷方法呀,我们给它改改。我们这里呢,把我们当前的它咱们拿过来,拿过来以后我这里给它起个名称,咱们就叫闷就可以了,好了,那它叫闷的话,我们把颜色呢,给它标记一下来,然后呢,把它的字体变粗一下可以了,哎,颜色变成我们的黄色吧,跟刚才一样行。那如果我的main方法没问题的话,那好,咱们一个一个来,首先第一个叫int I等于十,同学们,这不就是一个变量吗?这个变量就会保存到它的里面去,所以我们来复制,复制以后我放过来,我写上它,咱们叫int I,它等于十,同学们这个地方要稍微注意一下,我们这个I呢,是个基本数据类型,所以它等于的这个十啊,就保存在当前的黄色的小方块儿里面去,它不会保存到别的地方,就在这儿了。好,同学们,咱们继续继续,以后往下来,它叫test I。
07:33
这个test I什么意思?同学们,它表述的是我执行了一个新的方法吧,我执行了一个新的方法,按照咱们之前的理论,它有个压战的过程,那么压战的话,这个men它就会往下挪,懂我的意思吗?同学们,往下挪,往下挪以后上面就会有个什么,有一个新的战争被压出来了,它的名字就叫test。好,Test,记住同学们,这个test就是我执行当前的这个方法所创建的一块内存空间,好了,那么这个时候呢,用绿色来表示一下吧,用绿色。
08:06
那么这个时候有个问题了,什么问题呢?我这个test里面不是有一个叫做int I吗?这个I是我当前这个方法的一个参数,它也属于我们的变量,所以我们拷贝过来,拷贝过来同学们这个I它等于多少呢?它就等于十,为什么?因为咱们调用的时候,咱们写的是T,我们写了一个I,我把这个I的值十传过去,那么这个时候它的值也就变成了十,懂我的意思吗?同学们如果懂我的意思的话,那咱们接着往下,下面这什么意思?下面是I加十,十加十不就是20吗?20再重新复制给I,所以我们复制一下来,复制以后我们写上它,咱们就I,它等于I加上十,同学们,我相信这个不难吧,什么意思?我们的I加十就是20 20重新复制给它,这个一肯定等于20,没有任何的问题,对不对?好了,同学们,关键点来了,我们当前执行完这一步操作之后,这个方法是不是就已经结束了呀?
09:05
他如果结束的情况下,同学们,那这个是不是该弹战了,咱们刚才给大家讲过吧,一旦我的方法它执行完毕以后,是不是要弹战呀,把它弹出去啊,弹出去的话,那么我们这里它就没了,我为了演示方便,我这里就不把它弹出去了,干嘛呢?我要把它标灰,我要把它标灰呀,所以我这里呢,给它标上灰色,那么我们这里的这个文字呢,我们也给它标上灰色,但是我得区分一下,所以呢,我标上这个颜色啊好了。那我标上灰色以后,大家想想是不是该他执行了,他执行的话,他执行什么东西了,他执行一个打印操作,咱们叫做print,所以来咱们看看来拷贝,拷贝以后来我们写上它,咱们叫print,咱们的I。同学们讲到这儿了,你们现在能不能明白我为什么打印的结果是我们的十啊,因为你打印的I不就是他的值吗?你之前的那个值I跟我当前的这个I是两个不同的东西,他在内存的角度,它存在的两块不同的内存区域,这个大家能不能明白?
10:09
如果你能明白的话,现在你就会发现这个十已经被弹走了,已经看不见了,而这个十是不是还在呢?诶,就是这个道理,同学们能不能明白,如果能明白,这个十就没有问题。好了,同学们,这是我们给大家演示的第一个例子,那好,我们再来演示第二个例子,第二个例子呢,跟这个差不多,所以我们复制一下来,放过来以后把它我改一下,咱们叫做string,咱们叫做S,我把上面注掉。做掉以后,把这个我改一下,同学们跟刚才一样,S等于S加上十,好了,我这么写,写完了以后,我的S我写上它,咱们写上啊叫string,咱们叫S,咱们等于ABC对吧,ABC。好了,然后呢,我再写上一个S,然后呢,我再打印S。好,同学们,你们觉得现在的这个结果是多少呢?我相信有的同学说,老师这不就简单了吗?你之前讲过咱们的ABC字符串,诶,我们是个引用数据类型,那么引用数据类型的话,它应该在内存中有对象吧,如果有对象的话,那么它就拼串了,把十拼到了ABC的后面,那所以结果是不是应该是ABC10啊,所以应该是我们ABC10啊,不对,应该写在下面。
11:24
好了,我写在这个位置,大家想想对不对呢?我相信有的同学会这么想的,哎,所以我们运行一下,运行运行以后我们看结果你会发现不对,还是ABC,哎,老师这个我就不明白了,对吧?你前面讲过呀,你基本数据类型那个I呀,它的值存在的不同的区域,可是你是引用数据类型啊,那你这里为什么没有变成ABC10呢?同样道理,我们还是画图给大家解释一下。来我们来拷贝,拷贝以后我们画图给大家解释一下,大家可能就明白了什么意思啊,把这个咱们去掉,把它去掉。去掉以后,把这个去掉,然后呢,我们回来回到这边,回到这边以后,诶大家看一下,还是那个main方法先执行,如果他先执行的话,记住这边有一个特殊的地方,咱们来看我们的第一个叫string s等于ABC,所以我们拿过来向它。
12:15
我们叫做string s等于ABC没问题吧,但是你要记住同学们,咱们的这个ABC啊,它是一个我们的引用啊,所以说我们这里把这个红色的这个堆咱们拿过来,大家还记得吗?我们当时给大家讲过,我们的引用是放在我的堆里面的。所以呢,我这里写上它啊,咱们称之为叫做堆好了,如果它是堆的话,那么这个时候ABC我们就不能这么写了,为什么?因为基本数据类型的值我们是保存到我们的,占空间的,但是我们引用的字符串对象应该是在堆里面,所以啊,我们这里拿过来,拿过来以后我放到这边,好,我们写上它,给它一个这个颜色吧,我们写上它叫ABC。行了,然后呢,我的箭头呢,我就指向这个位置就可以了啊来我们的植物串指向它,诶大家会发现这就可以了,可以了,之后咱们接着往下看,它不叫test s吗?所以这个时候呢,我们把这个地方记住,又要给它复制了,干嘛呀,它要往下压了,压占了,压占了以后,那么这个时候我的箭头记录它是我们的S指向的,所以我们拷贝,拷贝以后放过来给它一个绿色。
13:25
给他一个绿色之后,这个名字我改成我们的test。好了,改完了之后干嘛呀,你会发现我们的这个方法它也有个参数,这个参数是S呀,所以说我们来复制同学们这个时候问题就在这儿了。我们的T的这个S,它到底是把这个S什么给他传过来了,我告诉大家传的就是这个当前的变量的值。他把当前这个变量的值传给他了,哎,老师把变量的值传给它什么意思?我们前面不是讲了吗?咱们这有个叫I等于十吗?他把十传过去了,十不就是变量的值吗?我们这也把变量的值给他传过去了,那老师传的是什么呀?传的就是引用变量的递值,说的简单点,他把这个箭头他传过去了。
14:13
为什么呢?因为你们指向了同一个内存地址啊,我们的内存就在这儿啊,所以说你也指向它,我也指向它,引用变量的值就是它的地址啊,好,那么这么写就可以了,写完了以后往下看,它写的S等于S加十,同学们,我不知道大家还有没有印象,咱们这里写上它,咱们叫S等于S加十,同学们记住了,我们这里的S是字符串,它加十就叫拼接字符串,它会把咱们的字符串拼接在一起,但是记住这有一个问题,它这个拼接是产生了一个新的字符串,这就意味着我们的S加十会产生一个新的字符串,这个颜色呢,我用紫色来表示,所以呢,就写上它,咱们叫ABC10。
15:01
它确实拼接了一个新的字符串,但是你要注意,它把这个新的字符串的这个地址给了S,就意味着S的箭头已经不再指向原来的ABC了,变成什么呢?变成我们的ABC10了,这个大家能不能明白,也就意味着我们这一步的操作,它等同于创建了一个新的字符串,然后把这个地址指向了他了。好了,这个如果大家能明白的话,咱们回来,回来了以后,我的这个test凯马执行完了,执行完了以后他就该弹战了,弹战的话,这就说明我们的颜色给它标灰一下来把它的颜色咱标灰。标灰以后把里面的文字呢,我们也给它标灰来,咱们标灰一下。诶,这样的话就可以了,可以了,之后回过头来,他开始执行打印操作了,打印操作的话,大家想想,诶,我们的S。同学们,现在你们能明白结果是什么了吗?它的结果是不是应该没有变呀,为什么这个S指向的是不是还是ABC没有任何的变化,如果没有变化的话,所以现在你执行我们的结果,你会发现应该跟我ABC没有任何的区别。
16:12
懂我的意思吗?同学们,诶,这就是我们第二个给大家演示的参数的情况,那好了,这是第二个,那么接下来咱们再来演示一个来给它复制,复制以后把这个呢给它来做掉。助掉以后呢,我这写上一个叫class,我们叫做user,好了,写完了之后,我们写上一个叫做string,给它来个name,我们写上他,我们叫做张,诶,咱们这里直接写上它就可以了啊好,写完了以后,同学们,我的这个地方我们改一下,咱们叫成什么呢?我们叫做UU,然后呢,我这里写上它很简单,咱们叫u.name它等于李四,就这么简单,好了,同学们,我现在回过头来,我上面这个地方呢,我改一下,把这个注掉吧。做掉以后,我写上一个叫UU等于new u对吧,创建对象,然后呢,u.name它等于张三好了,然后呢,我们写上它叫test,然后我们的user我传进去,接下来我打印咱们user.name。
17:13
同学们,我相信啊,这个代码也不难吧,但是现在的结果是什么呢?我这里呢,就不问大家了,我们来一块儿分析分析,如果你分析明白了结果是什么,就自然而然就得到了,来咱们分析分析,跟刚才一样,我们把咱们这个图啊,咱们复制一下来复制复制以后咱们往下放。往下放以后,首先还是没有上面的把这个去掉,去掉了以后把它拿过来,诶往上走,往上走以后大家看一下我们的这个代码,我们的代码当中首先是干嘛呀,New了个U,不要忘记同学们,我们的U可是一个对象啊,它就应该放在我的堆里面,没问题吧,所以我这写上它,咱们叫UR,哎,写个UR,然后呢,我在这个里面给它创建一个对象,所以拿过来。拿过来以后,同学们我放过来啊,这里我们给它一个我们的这个颜色,不要忘记它里面是有属性的呀,它里面如果有属性的情况下,我先写个U,诶我先放到这儿,然后呢,我们这边添加一个小方块,它的属性就在这儿了。
18:14
它的属性呢,我放过来我们就叫name就可以了啊好,它就叫name。行了,我写完了以后,那么这个时候我的箭头就应该指向我们当前的这个U对象了,诶就是这个样子,好,那么写完了,写完了以后不要忘记我后面呀,它有个问题,什么问题呢?不要忘记我们当前给这个对象的属性,我附了一个值叫ur.name它等于张三,这个U它指向的就是这个箭头它所代表的对象,那么这个name属性呢,就是这个对象中的它,所以我们复制一下,复制以后我们写上叫ur.name它等于张三,对吧?诶就这么写,你写完了以后,同学们不说别的吧,那么我们这个name不应该变成张三了吗?对不对,诶就是这样。好了,这一步咱们也做完了,做完了以后往下看,下面就叫test u诶又给它执行了一个方法,所以它我们就往下挪了,往下挪,往下挪,同学们往下挪,那么这个时候它往前走,往前走放过来,然后干嘛了呢?写个test。
19:17
好了,然后呢,把颜色我变成绿色。不要忘记同学们,这个箭头我要放回来,应该它指向的是这个U,诶好了,那行了,那现在呢,我们来操作一下我们的这个探子方法,它里面有个U,这个UR我们这也是有的,诶好了,放过来,放过来以后这个地方就把这个U的我传过去了,它如果把U的传过去的话,同学们千万要注意了,注意什么呢?我们是把我们当前这个引用变量的地址传给了他,就等同于把箭头传给了它,所以我们复制这个跟咱们前面讲字符串是一个道理,放过来。放过来以后,我们UR指向了他,没有任何问题,好接着往下,下面的是ur.name等于李四,大家看一下U箭头指向的他里面的name等于李四,所以把这个张三改成了什么李四的改完了以后,诶。
20:11
这个方法执行完了,它执行完了以后,我们当前的这个绿色,诶我们就应该干嘛呀,给它标灰了,谁来把它标灰。标灰了以后,它也就标成灰色了,来标成灰色可以吗?那可以了,以后大家想想这个箭头呢,这个箭头就是虚线了,为什么呢?没了呀,你连这块内存都没有了,这个引用不也就没了吗?好,接着往下,往下就回到了我们当前的这个打印,这个打印什么呀?u.name同学们注意一下。我这个U,诶,咱们写成它叫u.name你不要忘记这个U指向的箭头是它呀,它的name不就是里面的这个属性吗?大家想想变成什么了,变成了李四了,对吗?所以我们回过头来,我们运行一下看结果,你会发现结果就应该是李四,同学们现在能不能明白我们方法的参数传递到底是怎么传的,它就是怎么传的,所以啊,咱们这里可以总结出一句话来。
21:13
Java中。方法,参数的传递为我们叫值传递,什么叫做值传递啊,就是把咱们具体的那个参数的值给我传过去来,就是这个意思。那么这里涉及到两个问题,第一个就是我们的基本数据类型,基本数据类型你传递的就是我们的数值啊。你是一个我们的十,就把十传过去,如果是一个我们的处,就把处传进去,对不对,但是如果是引用数据类型,那么我们这个就传的是我们的引用地址,所以啊,我们只要把这个事情了解清楚了,再把老师画的这个图搞明白了,那么结果就能够正确的得到了,好同学们,我们方法的参数啊,我们就说到这里。
我来说两句