一、方法
1.1概念
方法是将有独立功能的代码块组织成为一个整体, 使其具有特殊功能的代码集。
注意事项:
- 方法必须先创建才能使用,该过程称为方法定义
- 方法定义后不是直接运行的,需要手动使用后才执行,该过程称为方法调用
- 引入方位的目的:
- 提高代码复用性。
- invoke 调用
- 机制
- 某个功能的代码只需写一遍
- 要使用这个功能,只需要给这个功能传递具体数据
- 功能完成后返回一个最终的结果
- 使用该方法称为“invoke/调用”
- 引入方法的优点
- 提高代码的复用性
- 提高代码的维护性//修改需求
- 方法的本质:
- 方法就是一段独立的代码片段,该代码片段可以完成某个特定的功能并能被重复使用
- 位置
- 方法定义在类体中,方法体外。
- 其位置不分先后。
- 方法体中不能再定义方法。
- 方法体中的代码有顺序
- 方法体中的代码符合Java语法
1.2 方法的定义/调用
- 语法_定义方法
- [修饰符列表] 返回值类型 方法名 (形式参数列表){
方法体;
} - 说明
- 修饰符列表
- 可选项,不是必须
- 目前统一写成 public static
- 方法的修饰符列表中有static关键字的调用:
- 类名.方法名(实际参数列表)
- 返回值类型
- 方法体代码结束后,通常需要返回其执行结果。执行结果可能是一个存在的值,该值的类型可以是Java中的任何数据类型(基本/引用)。
- 不是所有的方法都有返回值。当方法中代码不返回任何值时,返回值类型写void
- 返回值类型不是void,方法执行结束必须有一个返回值,语法是 return 数值;且数值与返回值的类型必须一致。
- 有void,不能有“return 值;”语句。
- 有void可以有“return;”语句。只要带有return关键字的语句执行,return所在方法结束。
- 方法名
- 只要是合法的标识符
- 见名知意
- 驼峰命名
- 最好是个动词
- 形式参数列表
- 形参是局部变量
- 形参个数可以是0到N个
- 多个用,隔开
- 形参中起决定性作用的是形参的数据类型,形参名字只是局部变量的名字
- 实参列表与形参列表必须满足
- 数量相同
- 类型相同
- 方法体
- 由大括号括起来,符合Java语法
- 修饰符列表
- [修饰符列表] 返回值类型 方法名 (形式参数列表){
1.3 无参数无返回值的方法定义/调用
- 格式
public static void 方法名(){
//方法体//函数功能
}
示例:public static void max(){
判断最大值代码块;
}
注:与main方法同级别,不要再main方法外,public 类内。 - 调用
类名.方法名();//括号内无内容,因为是无参数方法
说明:目前学习程度只学习了一个源文件中只有一个类,所有类名可以省略。当有多个类的时候,在class A中调用 class B中的方法就需要用 B.方法名(实参列表)调用。不过建议一个源文件中只写一个类class。
案例:两个数的最大值
//导包
import java.util.Scanner;
public class Max {
public static void main(String[] args) {
max();
}
//定义方法
public static void max(){
//创建对象
Scanner sc = new Scanner(System.in);
//接收数据一
System.out.println("请输入第一个数字");
int number1 = sc.nextInt();
//接收数据二
System.out.println("请输入第二个数字");
int number2 = sc.nextInt();
//判断最大值
int max = number1>number2?number1:number2;
//输出最大值
System.out.println("两个数中的最大值是:"+max);
}
}
方法调用训练
public class T1{
public static void main(String[] args){
System.out.println("main begin");
m1();
System.out.println("main over");
}
public static void m1(){
System.out.println("m1 begin");
m2();
System.out.println("m1 over");
}
public static void m2(){
System.out.println("m2 begin");
m3();
System.out.println("m2 over");
}
public static void m3(){
System.out.println("m3 begin");
//m1();//如果调用m1则构成死循环
System.out.println("m3 over");
}
}
1.4 有参数无返回值的方法定义/调用
- 定义:
格式
public static void 方法名(形参列表){…}
范例:
public static void maxNumber(int a,int b,int c,… ){…}
注意:
数据类型与变量名都不可缺少
多个参数之间用,隔开 - 调用
格式:方法名(参数);或者 方法名();必须有括号
范例:方法名(变量名/常量值);maxNumber(a); maxNumber(5);
方法名(变量名1/常量值1,变量名2/常量值2,…);maxNumber(a,b,c,…);
注:方法调用时,参数的数量和类型必须与定义方法时的数量和类型一致。 - 使用
需要对某些参数进行处理,且不需要返回值。
示例:最大值修改
//导包
import java.util.Scanner;
public class Max {
public static void main(String[] args) {
//方法一
//调用参数为常量
max(2,3);//调用参数为常量2
//方法一
//创建对象
Scanner sc = new Scanner(System.in);
//接收数据一
System.out.println("请输入第一个数字");
int number1 = sc.nextInt();
//接收数据二
System.out.println("请输入第二个数字");
int number2 = sc.nextInt();
//调用参数为变量
max(number1,number2);//调用参数为变量名
}
//定义方法
public static void max(int number1,int number2){
//判断最大值
int max = number1>number2?number1:number2;
//输出最大值
System.out.println("两个数中的最大值是:"+max);
}
}
深入return语句:
- 带return关键字的语句只要执行,所在方法执行结束
- 在同一个作用域中,return语句下不能编写任何代码。
- 带返回值的方法必须保证肯定有return语句执行
- 出现在void方法中,主要用来终止当前方法。return;后边不加值。也可终止main方法。
1.5形参和实参
形参是方法定义中的参数,包括数据类型和变量名,如:int a;
实参是调用函数时使用的变量,只有变量名或者常量,如:max(10);max(number);
参数传递时,传递的是变量中保存的值
1.6 有参数有返回值的方法定义/调用
- 格式
public static 数据类型 方法名(参数){return 数据;}
public static int max(int number1 , int number2 ){ return 100 }
public static boolean isEvenNumber(int number){return true}
注:- return后的值必须与定义方法时的数据类型一致
- 返回值可以是值,也可以是表达式,但是该表达式的值必须与返回值类型一致
- 调用
①方法名(参数);isEvenNumber(5);
②数据类型 变量名 = 方法名(参数);
boolean flag = isEvenNumber(5);
注:方法有返回值的时候,通常使用变量名接收,否则该值无意义。但是不接收返回值不报错。
案例
public class methodReturn {
public static void main(String[] args) {
//定义变量接受返回值
int result = max (13,22);
System.out.println(result);
//直接调用返回值
System.out.println(max(10,20));
}
public static int max(int a,int b){
//a大于b返回a
if(a>b){
return a;
}
//否则返回b
else{
return b;
}
}
}
1.7 方法注意事项
1.方法之间是平级,不能嵌套
2.void修饰的方法无返回值,不写return。return表示方法到这结束,不再继续执行后面的代码。
1.8 方法通用格式
- 格式:
public static 返回值类型 方法名(参数){方法体;return 数据}
public static:修饰符
返回值类型:无返回值,写void且一般不写return。
方法名 函数调用时的标识
参数 数据类型和变量名组成,多个参数用,隔开
方法体 完成功能的代码块
return 如果操作完毕有数据返回,return把数据返回给调用者 - 定义方法时,两个明确
明确有无返回值,没有写void,有则写相应的返回值类型以及return
明确参数的数据类型和数量 - 调用方法时
void类型直接调用
有返回值类型,推荐使用变量接收调用
二、方法重载
2.1 概述
代码功能相似的时候,尽可能让方法名相同;同理,代码功能不相似的时候,尽可能让方法名不同。
方法重载指同一个类中,定义的多个方法的之间的关系。满足下列条件的多个方法之间,相互构成重载
- 定义在同一个类中
- 方法名相同
- 方法的参数不同:数据类型/参数数量/参数顺序不同
2.2 方法重载的特点
- 重载针对的是方法的定义,与方法调用无关,调用还需参照标准格式
- 重载仅针对同一个类中的方法名和参数进行识别,与返回值无关。
案例:
package Day05;
//使用方法重载,判断两个数是否相等
public class MethodOverLoading {
public static void main(String[] args) {
byte c = 2;
byte d = 2;
boolean e = compare(c, d);//c=2,d=2
System.out.println(e);
System.out.println(c);
System.out.println(d);
}
//定义六种数值型变量的方法
/*
public static boolean compare(byte a, byte b) {
System.out.println("byte");
return a == b;
}
public static boolean compare(short a, short b) {
System.out.println("s");
return a == b;
}
public static boolean compare(int a, int b) {
System.out.println("i");
return a == b;
}
public static boolean compare(long a, long b) {
System.out.println("L");
return a == b;
}
*/
public static boolean compare(double a, double b) {//a:2.0,b:2.0
System.out.println("D");
System.out.println("a:"+a);
System.out.println("b:"+b);
return a == b;//a:2.0,b:2.0
}
/*
public static boolean compare(float a, float b) {
System.out.println("F");
return a == b;
}
*/
}
思考:为什么在compare方法中a,b的值为2.0,到了主方法中变成了2呢?
copmare方法中的a,b为形参,只作用在compare方法中,并不会作用到实参的值。
参考资料:
参考https://www.cnblogs.com/xuxinstyle/p/9672958.html
参考https://blog.csdn.net/u013309870/article/details/75499175
三、方法的参数传递
3.1 基本数据类型的参数传递
形参的改变不影响实参的值
思考:深入理解栈内存与堆内存
待定
3.2 引用数据类型的参数传递
形参的改变影响实际参数的值,比如:数组
3.3 案例
public class T13 {
public static void main(String[] args) {
//定义一个基本数据类型的变量
int a = 20;
System.out.println("调用方法前:" + a);
change(a);
System.out.println("调用方法后:" + a);
System.out.println("———————————" );
//定义一个引用数据类型的变量
int[] arr = {10,20,30};
System.out.println("调用方法前:" + arr[1]);
change(arr);
System.out.println("调用方法后:" + arr[1]);
}
//定义修改的方法
public static void change(int a){
a = 200;
}
//定义修改的方法
public static void change(int[] brr){
brr[1] = 200;
}
}
3.4 数组遍历
两个明确:
- 返回值类型
- 参数
- 数组名.length 表示数组长度
案例:遍历输出数组各个元素的值
public class T14 {
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
printarr(arr);
}
public static void printarr(int[] brr){
System.out.print("[");
for(int i = 0; i < brr.length; i++ ){
if(i == brr.length-1){
System.out.print(brr[i]);
}else{
System.out.print(brr[i]+" ,");
}
}
System.out.print("]");
}
}
最值问题:
public class T15 {
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
System.out.println(getMax(arr));
}
public static int getMax(int[] arr){
int max = arr[0];
for(int i = 1; i < arr.length; i++){
max = max > arr[i] ? max : arr[i];
}
return max;
}
}
四、方法的内存分配
- 概述
- 方法只定义,不调用。该方法不执行,并且JVM不会给该方法分配“运行所属"的内存空间。只有调用该方法,才会动态的给这个方法分配内存空间。
- JVM内存划分
- 方法区内存
- 堆内存
- 栈内存
- 栈数据结构
- 栈:stack,是一种数据结构
- 数据结构反应的是数据的存储形态
- 数据结构属于独立学科
- 程序员需提前精通数据结构和算法
- 数据结构:栈:先进后出 。
- 方法执行时,代码片段在哪里?方法执行的时候,执行过程的内存在哪里分配?
- 方法代码片段放在方法区中,属于.class字节码文件的一部分。字节码文件在类加载的时候,将其放到了方法区当中。所以JVM中的三块主要的内存空间中方法区内存最先有数据。存放了代码片段
- 代码片段虽然在方法区内存中只有一份,但是可以被重复调用。每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配。在栈中发生压栈动作。方法执行完毕,给该方法分配的内存空间全部释放,此时发生弹栈动作。
- 局部变量在“方法体”中声明,运行阶段的内存在栈中分配。