java的参数传递
编程语言都有方法(函数),方法里面有时候会有参数,我们称之为形式参数,主函数main函数里面也有参数,在主函数调用方法(函数)的时候,如果方法里面有形式参数,则需要在主函数将实际参数传递给形式参数,我们称之为参数传递,而且传递的参数顺序类型要与形式参数的顺序类型一致,下面我将就我目前知道的记录一下,方便我以后知道自己咋想的:
一、基本类型的参数传递:
基本类型四类八种,基本加string类型被称为字面量类型,但是string是引用类型,这里我们先讨论基本类型的参数传递:
public static void main(String[] args) {
int num=10;
method1(num);
System.out.println("main中的num为"+num);
}
public static void method1(int num){
System.out.println("主函数传过来的num为"+num);
num=200;
System.out.println("method修改之后"+num);
}
看到这代码的时候,我原本想的结果是:10 200 200
但是实际运行结果
main中的num没有被改变,还是10,为什么会有这种情况呢?这里就要说到内存的问题了,内存有两个存放位置,一个是栈内存一个是堆内存,方法都是存放在栈内存,一个方法需要占用一个栈帧,jvm都是main先进入占据栈帧,在main里面定义的变量num存放在main的栈帧里面,method方法也有自己的一个栈帧,形式参数num也存放在method的栈帧里面,此时传过来的num为10,method将num改成了200,但是main里面的num没有被修改,输出还是10.(画图理解吧),如果是基本类型的参数传递,传递的是数据
二、引用类型的参数传递:
java中引用类型有数组,字符串,枚举,class,interface,就来看看数组和字符串的参数传递的问题吧
public static void main(String[] args) {
int[] a={12,47,89};
method1(a);
System.out.println("main中的数组"+Arrays.toString(a));
String str="abc";
method2(str);
System.out.println("main中的字符串值"+str);
}
public static void method2(String str){
System.out.println("method中没有修改的字符串"+str);
str="hello";
System.out.println("method修改后的字符串"+str);
}
public static void method1(int[] a){
System.out.println("传递过来的数组"+Arrays.toString(a));
a[0]=100;
System.out.println("method修改后的数组"+Arrays.toString(a));
}
method里面的输出结果肯定是一样的,那么我们猜猜main中的数组和字符串输出结果有没有被修改值吧!
运行结果如下:
都是引用类型,为什么数组的值被修改,而字符串的值没有被修改呢?
这是因为在定义数组的时候,我们相当于new了一个数组,new的值都存放在堆内存里面,main中的变量都是存放在main的栈帧中,但是指向的是堆内存里面的new值,然后a数组作为参数传递到method方法里面,但是指向的是同一个堆内存的数据值,修改值的时候,是method里面修改,但是修改的是堆内存里面的数组值,此时需要输出的时候,main里面a的指向位置没有变,因此输出的是修改之后的数组值,对于数组,类,接口都是传递内存的地址值,这里指向的是跟main的参数指向的同一个内存地址。(画图好理解)
而对string类型来说,main里面str指向的是赋值常量abc,abc是存放在堆内存的常量池里面的一个值,main中的实际参数指向的地址值也传给了method中的形式参数地址指向,此时他们两个字符串都是指向常量池里面的abc,但是method又在常量池里面取出一个hello,也就是改变了method里面的地址指向,这时候method里面的str指向的就是常量池中的hello,而main中的str指向的还是常量池中的abc,这是因为string的底层是final,是常量。
string和基本类型都是字面量类型,如果说参数是字面量类型,传递的是数据,对于基本数据类型,他的变量和值都是在同一块内存,对于引用类型,他有两块内存,一块存变量,一块是被指向的地址存放地址