JavaSE基础day05方法和数组
一. 方法
(一) 方法的概述
1.方法的概念: 具有某种特定功能的代码段.某段代码功能经常使用,因此使用大括号,将这段代码包起来,起个名字,以后就使用这个名字来代替这段代码.
举例: Scanner类中的nextInt()方法,nextInt为方法名,每次需要通过键盘录入一个整数,调用nextInt方法即可.如若没有nextInt方法的封装,那么每次键盘录入数据,逻辑需要重新实现.
2.方法好处:
1)提高了代码的复用性(反复使用)
2)提高了代码的封装性,大括号中的内容,其他调用者看不到也无法直接访问
3)简化了软件设计的思维难度
(二) 方法定义
1.方法定义的格式
修饰符 返回值类型 方法名称(参数列表) {
方法体语句;
return语句;
}
2.详细解释:
1)修饰符: 目前全都写成 public static
2)返回值类型: 表示方法运行结果的数据类型.当方法功能运行完毕,有可能会有产出,就需要将产出的数据类型作为方法的返回值类型,返回给方法调用者.如果不需要返回结果,使用关键字void,表示方法没有任何返回值类型.
3)方法名称: 给这段代码起的名字,名字是一个合法的标识符并同时满足小驼峰原则(第一个单词的首字母小写,从第二个单词开始首字母大写).
4)参数列表: 这段代码要完成功能,可能会需要一些资源.在参数列表中,需要定义一些变量,内存中表示为容器, 在调用本方法的时候,会由外界传入数据,存储到这些变量容器中.使用变量符号,表示那些将来可能传入的数据.参数形式:数据类型 变量名, 数据类型 变量名...
5)方法体语句: 真正要完成该方法功能的执行逻辑.
6)return语句: 最终生产出来的结果,要返回给调用者,使用return语句返回.如果没有任何生产内容,可以不写return或者写return;用于表示方法结束.
案例1: 定义出一个方法功能,求任何两个整数的和
案例2 : 定义出一个方法功能, 比较两个浮点类型数据是否相等
案例3 : 定义出一个方法功能, 打印1-n整数(1-n任意整数打印, n为正整数)
(三) 方法调用
1.格式: 直接书写方法名称即可
方法名称(实际参数);
调用格式详解:
2. 方法调用的三种形式:
3.方法调用总体特点:
方法不调用,就不执行.
(四) 方法定义注意事项
1.方法定义注意事项:
1)方法不能嵌套定义,每一个方法都是独立的
2)方法的先后没有区别,都是平级关系
3)方法可以嵌套调用,甚至可以自己调用自己
2.参数列表:
1)形式参数: 在定义方法时使用,需要加上数据类型的参数,也就是对于变量进行声明.各个变量之间,使用逗号分隔.
2)实际参数: 在方法调用时使用,不能加上数据类型的参数,也就是对于变量进行赋值.各个实际参数之间,也使用逗号分隔,顺序必须和定义方法的形式参数顺序一致.
3.return语句:
1)return语句表示方法结束了,也同时表示方法的产出内容.
2)如果方法没有具体的返回内容,可以写成return; 此时的return语句可以省略,返回值类型必须写成void.
3)如果方法有具体的返回内容,那么return后面就需要加上返回具体数据,返回值类型必须和return语句后面数据的数据类型一致.
4)谁来调用当前方法,return语句就将当前方法的数据结果返回给谁.
(五) 方法内存理解
1. 栈内存概念:
JVM虚拟机运行代码: JVM虚拟机就是运行Java代码的容器,运行时需要在内存中开辟空间,JVM将其占有的内存空间划分成5块空间区域,其中一块空间,称为栈内存
栈内存: 代码中的方法运行, 需要在栈内存中开辟空间运行; 方法调用时进栈, 方法运行完毕, 出栈, 占有的内容空间释放(方法弹栈死亡)
(六) 方法练习
案例1: (钱就表示参数, 酒表示返回值结果)
1)王老头去第一次买酒,到商店发现没有带钱,那就没有买回酒.输出:钱都没有买个寂寞.
2)王老头去第二次买酒,到商店发现没有带钱,但是老板娘是熟人,一番沟通,带回了一瓶二锅头.
3)王老头去第三次买酒,刚发了工资,到商店,给钱之后,老板见钱眼开,拿钱跑路,只留老头一人凌乱.
输出: 城市套路深,是否回农村???
4)王老头去第四次买酒,到商店给钱之后,老板给王老头一瓶江小白.
方法的设计关于参数和返回值组合:
1. 有参有返
2. 有参无返
3. 无参有返
4. 无参无返
(七) 方法重载
1.方法的重载: Overload,超载
在同一个类中,方法名相同,参数列表不同,与返回值类型无关的多个方法,称为重载
2.举例:
1)要求做两个任意整数求和
2)要求做三个整数求和
3)要求做2个double浮点类型求和
场景: 在功能上类似的三个求和方法,每个方法都有自己的方法名,不便于记忆,如果让类似功能具有相同方法名, 通过参数列表不同区分多个方法,如此也可以实现,这就是方法重载.
3.参数形式不同的情况:
参数类型不同;参数个数不同;参数类型的顺序不同;参数的名称不同(不算)
4.方法重载的好处:
1)没有重载的时候,相同逻辑相同功能的代码,需要定义很多个方法名称.调用者在记忆方法名称的时候,就有很大的负担.
2)有重载之后,相同功能逻辑的方法,只需要记忆一个名字.
5.当前学习过的常见重载:
println方法,任意类型的数据,都可以放到这个方法中打印
在System.out类型中,将各种数据类型的打印方法,都定义出来了,都起了println方法的名称
public class MethodOverload { public static void main(String[] args) { System.out.println(getSum(3,4,5)); System.out.println(getSum(3,6)); System.out.println(getSum(1.2,6.7)); System.out.println("abc"); System.out.println(true); } // 重载方法参数列表不同体现: // 1. 参数个数不同 // 2. 参数数据类型不同 // 3. 不同类型参数之间的排列顺序不同 // 注意: 参数名称与重载无关 // 1. 求和1 public static int getSum(int x, int y){ return x + y; } /* 此方法与上面的getSum算作方法重复定义, 报错 public static int getSum(int a, int b){ return a + b; }*/ // 2. 求和2 public static int getSum(int x, int y,int z){ return x + y + z; } // 3. 求和3 public static double getSum(double d, double d1){ return d + d1; } public static void getString(String str,double d){ System.out.println(str + d); } public static void getString(double d,String str){ System.out.println(str + d); } }
二.数组
(一) 数组概述
1.数组含义: 存储相同类型数据的容器.
2.应用举例:
现在需要统计某公司员工的工资情况,假设该公司有50名员工,例如计算平均工资、找到最高工资等.
a: 没有数组,首先需要声明50个变量来分别记住每位员工的工资,然后再进行操作,但是多个变量彼此之间没有关联, 没有关系性,会使得操作过程很麻烦,而且错误率也会很高.
b: 有数组, 可以将50个员工的工资全部存储在数组中,给这个容器起名,而数组中的每一个数据都有对应的编号, 根据存入的顺序编号从0开始,依此类推,通过"容器名 + 数据编号",可以定位每一个数据,从而更便于操作数据
3.数组特点:
1)存储数据长度固定的容器, 当定义一个数组时, 必须指定数组的长度(可以存储的数据个数)
2)存储数据的数据类型要一致
(二) 数组动态初始化
1.含义: 只指定数组长度不指定数组元素值.
2.数组的定义:
数据类型[] 数组名称 = new 数据类型[数组长度];
数据类型 数组名称[] = new 数据类型[数组长度];
3.详细解释:
数据类型: 创建的数组可存储的数据类型
[]: 表示数组
数组名称: 数组本身也是一个变量,用于存储数组地址的变量名
=: 赋值符号,将数组的地址,赋值给数组名称
new: 关键字,创建数组使用的关键字,用于在堆内存中给数组开辟存储数据的空间
数据类型: 和前面的数据类型保持一致
数组长度: 表示数组容器中可以存储多少个元素
4.举例:
int[] arr = new int[3];
定义出一个数组,数组名arr, 数组中可以存储3个int类型整数
public class 数组动态初始化 { public static void main(String[] args) { int[] arr = new int[3]; /* [I@1b6d3586 (不需要记,只需要知道数组名是一个内存地址即可) [ : 一维数组 I : 大写字母I, 数组中存储的数据类型int首字母大写 @: 没有含义,普通字符串,做前后分隔 1b6d3586: 十六进制数, 数组在内存中位置 */ System.out.println(arr); double[] arr1 = new double[5]; System.out.println(arr1); String[] arr2 = new String[4]; System.out.println(arr2); } }
(三) 数组的访问格式
1.索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素.索引的范围: 0---数组长度-1.
注: 索引也称为下标,角标,脚标
2.索引访问数组中的元素:
数组名[索引] = 数值; 为数组元素赋值
变量 = 数组名[索引]; 获取出数组中的元素
3.当定义出一个数组时, JVM虚拟机会默认为数组中的每一个元素进行默认的赋初值动作, 根据不同数组中存储的数据类型不同, 初值也不同
整数 : 0
浮点类型 : 0.0
char类型 : ‘ \u0000’
boolean类型 : false
引用数据类型 : null, null表示引用数据类型为空
public class 数组访问 { public static void main(String[] args) { // arr数组索引范围0-2 int[] arr = new int[3]; // 1. 数组元素赋值: arr[索引] = 数据值; // 2. 数组元素取值: 变量 = arr[索引]; arr[0] = 79; arr[1] = -3; arr[2] = 888; System.out.println(arr[0]); int i = arr[1]; System.out.println(i); System.out.println(arr[2]); int[] arr1 = new int[2]; /* 当定义出一个数组时,JVM会为数组中的每一个元素进行默认的赋初值动作: JVM根据数组中存储的不同数据类型给不同的初值 1. 整数: 0 2. 浮点: 0.0 3. 字符类型: '\u0000' 空 4. 布尔类型: false 5. 引用数据类型: null */ System.out.println(arr1[0]);// 0 boolean[] arr2 = new boolean[5]; System.out.println(arr2[3]);// false String[] arr3 = new String[5]; System.out.println(arr3[0]);// null } }
(四) 数组静态初始化
1.含义: 在创建数组时,直接将元素确定的定义方式
2.格式:
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ..., 元素n};
注意事项:
1)在第二个方括号中,不能写数组元素个数
2)元素值的罗列,元素和元素之间,使用逗号分隔
3)罗列出来的元素值,数据类型必须和声明数组时数据类型一致
3.简化格式:
数据类型[] 数组名 = {元素1, 元素2, ..., 元素n};
注意事项: 不能分成两行写
public class 数组静态初始化 { public static void main(String[] args) { // 1. 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ..., 元素n}; // 2. 注意事项: 静态定义时, 数组长度不能写, 写了就报错 int[] arr = new int[]{12,33,-8,99}; System.out.println(arr[3]);// 99 // 3. 静态初始化还能简写: // 数据类型[] 数组名 = {元素1, 元素2, ..., 元素n}; // 简写方式注意: 不能分成两行写 double[] arr1 = {3.14,5.56,-0.7}; double[] arr2; arr2 = new double[]{3.4}; // arr2 = {6.68}; } }
1 int[] arr; arr = new int[5]; arr[0] = 1; arr[1] = 2; arr[2] = 3; arr[3] = 4; arr[4] = 5; 2 int[] arr; arr = new int[]{1,2,3,4,5}; 3 int[] arr = {1,2,3,4,5}; 4 错误 int[] arr; arr = {1,2,3,4,5}; 5 int[] arr = new int[]{1,2,3,4,5}; 6 int[] arr = {1, 2, 3, 4, 5}; 7 错误 int[] arr = new int[5]{1,2,3,4,5};
(五) 数组的内存理解
5.1Java的内存划分和作用
1.内存概念: 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存.
2.Java虚拟机的内存划分
Java虚拟机要运行程序,对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式.类比一处房子,房子中有厨房,专门进行做饭;有卧室,专门进行休息;有书房,专门进行学习和工作...因此内存中的空间就像房子要分门别类进行空间的管理使用.
3. JVM的内存划分:
5.2数组在内存中的存储
1.一个数组的内存图
数组引用的输出的结果是地址,是数组在内存中的地址.new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址.
2.两个数组的内存图
引用数据类型每次new,都在内存中开辟新的空间地址.
3.多个引用指向同一个数组空间
任意一个引用修改了数组中的内容,其他引用访问到的就是修改后的数据.
(六) 数组的异常
1.异常(Exception): 表示在Java代码编译和运行过程中,出现了不正确的,不正常的,不符合实际场景的情况,统称为异常
2.数组中常见的异常有两种:
a: 数组索引越界异常
b: 空指针异常
6.1 数组索引越界异常
1.索引越界异常:
ArrayIndexOutOfBoundsException
数组 索引 超出 边界 异常
2.发生索引越界异常原因:
使用的索引在数组中不存在
3.代码分析:
观察一下代码,运行后会出现什么结果
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[3]);
}
创建数组,赋值3个元素,数组的索引就是0,1,2,没有3索引,因此我们不能访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常.在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码.
4.越界异常避免方案
不要访问不存在的索引,使用索引时,验证索引在"0--数组长度-1"范围
5.数组的长度属性: 每个数组都具有长度,Java中通过数组的length属性获取数组长度
语句为:数组名.length
public class 数组索引越界异常 { public static void main(String[] args) { double[] arr = {12.1, 13}; // ArrayIndexOutOfBoundsException : 3 // 数组 索引 超出 边界 异常 // 发生异常原因: 使用了数组中不存在的索引,一律越界异常 // System.out.println(arr[3]); // System.out.println(arr[-1]); // 解决越界异常方案: 使用索引时候, 不要超出数组正确索引范围 // 正确范围 0---数组长度-1 // 数组中长度获取方式: length属性, 数组名.length System.out.println(arr.length); int ele = getElementFormArray(7); System.out.println(ele); int ele1 = getElementFormArray(2); System.out.println(ele1); } // 定义出一个方法: 获取int[]数组中指定索引位置元素 public static int getElementFormArray(int index){ int[] arr = {14,55,-6,7}; // if (index >= 0 && index <= arr.length-1){ // index <= 5 index < 6 if (index >= 0 && index < arr.length){ return arr[index]; }else{ System.out.println(index + "索引位置在arr数组中不存在,返回默认值0"); return 0; } } }
6.2 空指针异常
1.空指针异常
NullPointerException
空 指针 异常
2.发生空指针异常原因:
当引用数据类型值设置为null(前提),证明这个变量引用没有指向任何堆内存地址,但仍然想通过这个变量引用访问堆内存中数据,就会报出空指针异常
注: null,即为空,用于表示在栈内存的引用中,不记录任何堆内存的地址
3.代码分析:
观察一下代码,运行后会出现什么结果
public static void main(String[] args) {
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
}
arr = null这行代码,意味着变量arr将不会再保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出NullPointerException 空指针异常.在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码.
4.空指针异常避免方案
在使用引用之前,先判断该引用的值是否为null,不为null再去访问
public class 空指针异常 { public static void main(String[] args) { // arr容器不存在 int[] arr = null; // NullPointerException // 空 指针 异常 // 空指针异常发生原因: 发生前提,数组的值设置为null, 还要使用数组名访问堆内存中的数据,才发生异常 // System.out.println(arr.length); // System.out.println(arr[0]); // 解决空指针方案: 使用数组之前, 验证数组的值不为null即可 if(arr != null){ // arr访问 System.out.println(arr[0]); }else{ System.out.println("数组为null无法操作"); } } }
代码中异常的控制方式
public class 数组中的异常控制案例 { public static void main(String[] args) { // int[] arr = {12,13,14,15}; // int[] arr = {12,13}; int[] arr = null; getEle(arr,2); } // 定义出一个方法: 求任意int[]数组中指定索引位置元素 public static void getEle(int[] arr, int index){ // 验证数组合法: 先验证数组不为null.后验证索引范围问题, 否则空指针可能控制不住 if(arr != null && index >= 0 && index < arr.length){ System.out.println(arr[index]); }else { System.out.println("arr数组为null或者索引位置越界"); } } }
(七) 遍历数组元素
1.数组遍历: 就是将数组中的每个元素分别获取出来,这就是遍历.
2.分析思路:
通过循环,访问到数组中所有元素的索引,0到lenght-1
通过索引,访问到对应元素,数组名[索引]
public class 数组遍历 { public static void main(String[] args) { double[] arr = {12,13,-0.9,99,88,0,67}; double first = arr[0]; double second = arr[1]; double third = arr[2]; if(arr != null){ // 数组遍历思想: 利用循环依次将数组中的每一个元素获取到 for(int index = 0; index < arr.length; index++){ double ele = arr[index]; System.out.println(ele); } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)