一.方法的调用及参数的传递
1.方法的调用
1.1 定义方法的语法
[访问修饰符] 返回值类型 方法名([参数类型 参数1,参数类型 参数2,…]){
方法体
}
详解:
访问修饰符:用于修饰这个方法的调用范围,目前默认public static
返回值类型:无返回值就写void或者方法执行后返回的结果的数据类型,方法执行之后会将结果返回
方法名:给方法取的名字,遵循标识符规则
参数类型,参数名:同时定义,方法在执行时未知的数据,需要在调用方法时进行传递值.参数类型表示这个参数的数据类型,参数名就是参数的名称,这个参数名可以在方法体中使用.
方法体:这个方法具有的功能代码块.如果方法体中需要一些未知的数据作为执行条件,那么这些数据可以作为参数进行传递.
1.2 方法调用的两种方式:
1.2.1 对象名.方法名(参数)
1.2.2 直接写方法名调用,但方法必须是static修饰的
例如:
//获取字符串的第一个字符
public static char method1(String str){
return str.charAt(0);
}
//调用方法:
String s="abc";
//1.
创建对象;
对象名.method1(s);
//2.直接通过方法名调用静态方法(即static修饰的方法)
char c=method1(s);
2.方法的参数传递
2.1方法的分类
根据方法的参数不同和返回值不同,可以将方法分为以下四类:
2.1.1.无参无返回值方法
2.1.2.无参有返回值方法
2.1.3.有参无返回值方法
2.1.4.有参有返回值方法
针对有参方法需要注意以下三种情况
情况一:方法的参数是基本数据类型时传递的是值(将实参的值传递给形参) ,且形参的值的改变不会影响实参的值同时改变
//参数是int类型
public static void add(int num){
num++;
System.out.println("方法中 num 的值:"+num);
}
//调用:
int n =10;
System.out.println(n);
add(n);//n是实参,将实参n的值赋值给形参num
System.out.println("方法外面 实参的值:"+n);
//结果输出:num的改变不会改变n 的值 ,因为是两个独立的内存
方法中 num 的值: 11
方法外面 实参的值:10
情况二: 当参数的数据类型是引用数据类型时传递的是地址(String类型除外)
例如 数组 、类
//数组的调用:
// 方法的比对 参数是数组类型时
public static void add(int [] arr){
arr[0]++;//根据传递来的地址改变数组的第一个元素的值
System.out.println("方法中 arr[0]="+arr[0]);
}
//调用:
int [] array ={10,20};
add(array);// array中存放的是数组的地址。会调用参数是数组的add方法
System.out.println("方法外面的 arr[0]="+ array[0]);
//结果:
方法中 arr[0]=11
方法外面的 arr[0]=11
//类的调用:
public static void addAge(Student student){
// 将学生的年龄 获取 自加
int age = student.age;
age++;
// 再重新赋值
student.age=age;
}
//调用:
Student student = new Student(); // age默认为 18
System.out.println("方法调用之前: "+student.age); // 18
addAge(student); // 传的地址
System.out.println("方法外面 学生的年龄:"+student.age);//19
//
结果输出: 方法调用之前: 18
方法外面 学生的年龄:19
/**
以上方法调用 的结论:
* 对于参数为引用数据类型,方法外面和方法内部公用同一块内存.也就是说,参数在传递时,将引用类型的地址赋值给方法的形参
* 对于基本数据类型,方法的实参数将值的副本赋值给形参,这样形参的改变不会影响实参的值
* 原因: 引用数据类型在参数传递时传递的是地址(JVM对于堆内存的大小不可控)
* 基本数据类型在参数传递时传递的是值
*
*/
情况三、 当参数是String类型时 ,String是引用数据类型,但是在参数传递时是与基本类型一样
public static void main(String[] args) {
// 参数是字符串
String uname ="李泽文";
sayHello(uname);
System.out.println("我最后对"+uname+"sayHello");
}
public static void sayHello(String name){
name="祝一帆";
System.out.println("我对"+name+"sayHello");
}
//结果:
我对祝一帆sayHello
我最后对李泽文sayHello
3.方法的递归调用
3.1定义
在一个方法中,运行方法调用自身,这样的调用称为方法的递归调用.为了避免方法调用时出现死循环,递归调用中必须定义 方法结束调用的条件即需要给程序一个结束的出口.
3.2方法递归调用执行流程:
public static void m3(int i){
if(i==5){
return ;
}
System.out.println("这是m3方法开始i :"+ i);
i++;
m3(i);
System.out.println("m3方法的结束 i:"+ i );
}
public static void main(String[] args) {
m3(0);
}
图解:
//关键字new创建对象的过程即编译:
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);
第一行创建了一个 Point 类的对象,第二个和第三个创建了一个Rectangle 矩形类的对象。
这些类的对象的创建都包含了三个部分(详细讨论):
初始化Initialization:new运算符,随后调用构造函数,初始化新创建的对象。
1.声明引用变量
声明Declaration:粗体代码是将变量名称与对象类型关联的变量声明.
2.实例化一个类对象即创建对象.
实例化Instantiating :new关键字是一个java运算符,它用来创建对象.
new运算符实例化一个类对象,通过给这个对象分配内存并返回一个指向该内存的引用.
new运算符返回它所创建的对象的引用,此引用通常被分配给一个合适的类型的变量, 如:Point originone =new Point(23,94).
就是“创建一个Java类对象”-----给类对象分配内存并返回指向该内存的引用.
3.初始化对象实例.
初始化Initialization:new运算符随后调用构造函数,初始化新创建的对象.
就是调用类对象中的构造方法,对类的实例数据赋初值.
//https://www.cnblogs.com/KingIceMou/p/7245446.html
//https://zhidao.baidu.com/question/36708169.html
//https://blog.csdn.net/zhangsanfeng2009/article/details/80900963
二.一维数组
1.一维数组的创建
方式一 动态初始化 : 初始化时只指定数组长度,由系统为数组分配初始值.
数组存储的数据类型 [] 数组名字 = new 数组存储的数据类型[长度];
方式二 静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度.
数据类型 [] 数组名=new 数据类型[]{元素1,元素2,...};
方式三 静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度.
数据类型 [] 数组名 ={元素1,元素2,...};
2.数组的访问
数组的访问通过索引即下标访问,数组的下标默认从0开始.
3.一维动态数组
//添加元素到末尾
public static int[] addEle1(int [] array,int num) {
//创建临时数组的长度
int [] temparray=new int[array.length+1];
//将目标数组的元素copy到临时数组的内存中
for (int i = 0; i < array.length; i++) {
temparray[i]=array[i];
}
//将要添加的元素放入临时数组中
temparray[temparray.length-1]=num;
//将临时数组的地址赋值给目标数组
//array=temparray;
return temparray;
// return array;
}
//调用:
int arr[]= {1,2,3};
arr=addEle1(arr,6);
//int[] arr1=addEle1(arr,6);
System.out.println("数组arr"+Arrays.toString(arr));//数组arr[1, 2, 3, 6]
// System.out.println("数组arr1"+Arrays.toString(arr1));//数组arr1[1, 2, 3, 6]
疑点:要返回数组的原因:return temparray;
(需要明白数组在内存中的分配方式)
动态数组操作内存分布图:

我们知道形参array和temparray的作用域是在方法addEle1中,方法执行完内存空间会自动回收.变量声明时,JVM在栈中为局部变量array和temparray分配内存,array指向原数组在堆内存中的内存空间,temparray指向新数组在堆内存中的内存空间.当把temparray存储的地址赋值给array时,array改为指向新数组在堆内存中的内存空间.而这些改变并不影响或者说实参arr存储的地址即实参arr仍指向原数组在堆内存中的内存空间,即图中的(1).若不执行return temparray语句,由于方法执行完array和temparray的内存空间会被自动回收,导致没有引用变量指向新数组空间,使得这种改变没有被保留即“添加元素至数组末尾”操作没有成功.若返回即执行return temparray语句并在主函数中接收即将新数组第一个元素的地址赋值给arr,使得arr改为指向新数组在堆内存中的内存空间即(2),从而表面上对数组arr的改变得以保留即操作成功.
本文详细介绍了Java中方法的调用和参数传递,包括方法定义的语法、调用方式、参数传递的原理以及递归调用。在参数传递部分,特别讲解了基本类型和引用类型的区别,并通过实例解释了String类型的特殊性。此外,还探讨了一维数组的创建、访问以及动态数组的操作,强调了在方法中修改数组后如何保留变化的重要性。
2610

被折叠的 条评论
为什么被折叠?



