Java方法的调用以及参数传递

本文详细介绍了Java中方法的调用和参数传递,包括方法定义的语法、调用方式、参数传递的原理以及递归调用。在参数传递部分,特别讲解了基本类型和引用类型的区别,并通过实例解释了String类型的特殊性。此外,还探讨了一维数组的创建、访问以及动态数组的操作,强调了在方法中修改数组后如何保留变化的重要性。

一.方法的调用及参数的传递

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 Point2394).
  就是“创建一个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的改变得以保留即操作成功.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值