第四天 Java语言基础

一、函数的概念

      1)什么函数

                函数就是定义在类中的具有特定功能的一段独立小程序,并能被多次使用。

      2)问题引入

                在昨天讲述使用循环嵌套画出矩形。但有问题,每次要画矩形都要写很多重复性的代码,能不能将这些代码画矩形的代码封装起来,在需要画矩形的时候调用这段封装的代码呢?

                问题:要画矩形,需要不断使用该for嵌套代码。造成代码复用性很差。

                解决:定义一个功能用于画矩形,每次只要使用该功能即可。这样提高复用性。

          第四天 Java语言基础

          第四天 Java语言基础

      3)函数的定义格式

                修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...)

                {

                       执行语句;

                       return 返回值;//return关键字是用于结束该功能。并将后面的具结果返回给调用者。

                       //必须有return语句。

                }

                注意:函数的返回值类型如果是void时,return语句可以省略不写;void表示的是没有返回值的情况。

      4)如何定义函数

                函数就是一个功能,功能就需要两部分:

                1、函数运行完的结果是什么;2、函数运行时有未知参数吗。

                定义函数时,时刻把握如下两个明确,基本就可以完成函数的定义:

                明确1:这个功能的结果是什么?其实就是明确返回值类型。

                明确2:这个功能需要未知内容是什么? 其实就是明确参数列表。

      5)定义函数举例

                需求:需要一个方法,进行加法运算,获取两个整数的和。

           第四天 Java语言基础

      6)函数的执行过程

                以下代码的执行顺序

           第四天 Java语言基础

           第四天 Java语言基础    

           第四天 Java语言基础

      7)函数的内存加载

          第四天 Java语言基础

                上面代码执行的内存图解

          第四天 Java语言基础

                图解说明:首先会加载main方法加载进栈内存中,并执行main方法中的代码,分别给a变量开辟空间并存放3,给b变量开辟空间存放4。当程序执行到int sum = getSum(a,b);时,会将getSum函数加载进栈内存中,同样在getSum所属的栈区域中开辟a和b变量空间,接受main方法中的getSum(a,b);传递的值。然后执行getSum函数中的代码,当getSum函数执行结束后,函数会出栈(弹栈)。程序回到main方法的调用语句int sum = getSum(a,b);处,并将getSum方法执行完返回的结果赋值给sum变量,程序继续往下执行。打印sum的值。

二、函数的重载

      1)重载的引入

                两个数相加,需要一个函数名字getSum,三个数相加需要一个函数名字getSum2,那如果有100个数相加,不是就需要getSum100了?那是不是在调用函数的时候还需要去记住哪个函数名对应多少个参数?这很显然是不可能的了。java为我们提供了重载这个功能,使用重载就可以解决这个问题。

      2)重载的概念

                在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可,这时就形成了重载。重载和返回值类型无关

      3)重载举例:

                需求:完成任意乘法表打印。

          第四天 Java语言基础

      4)重载练习题

                void show(int a,float b,char c){}

                下列哪些函数和给定函数重载了。

                a.int show(int x,float y,char z)             //没有重载,这个函数不允许和给定函数存在于同一个类                                                             中。因为会产生调用的不确定性。

                b.void show(float b,int a,char c)           //重载了,参数类型不同。

                c.void show(int c,float a,char b)           //没有重载,和给定函数一样。不允许存在。

                d.void show(int a,int b,int c)                //重载了,因为类型不同。

                e.double show()                                 //重载了,因为个数不同。

      5)函数命名规范

                在定义函数时,函数名名不能使用关键字和保留字。

                回忆类名的定义规范:单词的首字母大写,采用驼峰式;由有实际意义的名词或名词短语构成:如:Student,  StudentScore,

                函数名规范:

                      第一个单词的首字母小写,采用驼峰式;由有实际意义的动词或动词短语。如:getSum

三、数组的定义

                经过前面的学习,知道了变量空间是可以存放数据的,但是每一个变量空间只能存放一个数据,可是当数据非常多的时候怎么办?比如全班同学的年龄,年龄是一个int类型的数据,可以开辟int空间存放。可是全班这么多同学,难道我们都要一个一个变量空间去定义在存放数据吗?Java有没有提供其他的方式可以存放同一类型的多个数据呢?

      1)数组的概念

                数组是同一种类型数据的集合;即能够存放多个相同类型的数据的容器。

      2)数组的定义方式

                数组是存放多个数据的容器,Java中需要使用new关键字来创建容器,在创建容器时也要明确容器的大小,即容器中存放数据个数。

                元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

                int[] arr = new int[3];//通过new关键字创建了一个长度为3,元素类型是int的数组实体。

      3)数组的好处

                 数组可以存储多个数据,而且可以对数据进行编号,从0开始。操作元素完成可以通过编号(索引)完成。

                 int[] arr = new int[3];

                 arr[0] = 3; //给数组编号(角标)为0的空间中存放int类型的常量值3

                 System.out.println(arr[1]);//输出数组编号为1空间中的值。

四、数组内存图解

      1)Java的内存分配

                Java对内存空间的划分:五部分:栈,堆,方法区,本地方法区,寄存器。

                栈内存:存储都是局部变量。只要是在方法中定义的变量都是局部变量。一旦变量的生命周期结束该变量就被释放。

                堆内存:存储都是实体(对象),每一个实体都有一个首地址值。堆内存的变量都有默认初始化值。不同类型不一样。int-0  double-0.0  boolean-false char-'\u0000'。当实体不在使用时,就会被垃圾回收机制处理。

      2)数组的内存分配

                int[] arr = new int[3];

                arr = null;

          第四天 Java语言基础         

                图解说明:程序执行main方法时,会先在堆内存中开辟数组空间,并为其分配内存地址0x34(假设)。数组各个空间都有默认的编号(角标或索引),接着给数组各个存储空间默认初始化为0。到底数组创建结束,将数组的内存地址赋值给main方法的数组引用变量arr。程序继续执行,将arr引用变量赋值为null,即arr不再指向堆中的数组实体。这时这个数组实体将会编程垃圾,等待垃圾回收机制收走。

五、数组的常见问题

      1)数组角标越界异常

                ArrayIndexOutOfBoundsException:访问到了数组不存在的索引时,会发生该异常。

          第四天 Java语言基础

      2)空指针异常

                NullPointerException:当使用没有任何实体指向的引用变量操作实体时,运行会发生该异常。

          第四天 Java语言基础

六、数组的应用(遍历、求和、最值)

      1)数组的第二中定义格式

                 前面讲过定义数组,可数组的值都是默认值。有时候需要在定义数组时候就把具体的数据存放在数组中。那么看看数组的第二种定义格式:

                 元素类型[] 数组名 = new 元素类型[]{元素1,元素2,元素3...元素n};

                 简化格式:元素类型[] 数组名 ={元素1,元素2,元素3...元素n};

           第四天 Java语言基础

      2)遍历数组

                 当需要操作数组的每个空间时,需要从角标0为开始,一直操作到数组最后一个空间,发现数组的角标在有规律的递增。可以使用循环提供数组角标。

           第四天 Java语言基础

                 从上述代码发现,数组中的数据如果较多时,不可能去数数组中到底有多少个元素,具体需要循环多少次。数组这个实体对象有一个属性length,这个属性中记录当前引用所属数组实体中具体有都少个元素。

          第四天 Java语言基础

           第四天 Java语言基础

      3)案例:数组求和

                 需求:求数组中所有元素的和

                 思路:

                       1、需要定义个功能,用来求数组中所有元素的和值。        

                       2、定义功能,必须搞清楚两个明确:

                 步骤:

                       1、定义变量记录和。

                       2、通过循环对数组进行遍历。

           第四天 Java语言基础

      4)案例:数组求最值

                 需求:获取多个整数中最大值。

                 思路:

                       1、数据多了为了便于操作,先存储起来。需要容器。用数组。

                       2、多个数据需要进行比较。每次都有较大的数,需要记录下来和下一个数比较。

                       3、将数组中的元素都比一遍。最后,就有了最大值。

                 步骤:

                       1、需要数组。

                       2、定义一个变量记录住较大的数。

                       3、对数组进行遍历。让元素和较大的值进行比较。

                            如果元素大于较大的数,用变量记录该元素。

                       4、遍历完成后,变量中记录就是最大值。

           第四天 Java语言基础