Java提供了两种参数的传递机制:值传递和引用传递
基本类型:按值传递
引用类型:按引用传递
参数传递
值传递:
- 对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递: - 对非基本类型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。
基本类型和引用类型的不同
基本类型:值就保存在变量中
引用类型:变量保存的是实际对象的地址。实际对象保存着内容
int num = 10;
String str = "hello";
赋值运算=
我们要理解=的作用。
对于基本类型,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于引用类型,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。
num = 20;
str = "java";
方法的参数传递
参数传递基本上就是赋值=操作
例子
1.例子一
package com.example.demo002.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
public class test {
private static final Logger logger = LoggerFactory.getLogger(test.class);
public static void main(String[] args) {
int number = 100;
System.out.println("main number:" + number);
change(number);
System.out.println("change after main:" + number);
}
public static void change(int number) {
number = 200;
System.out.println("change number" + number);
}
}
main number:100
change number200
change after main:100
解析:只是副本改变了
2.例子二
public class test {
private static final Logger logger = LoggerFactory.getLogger(test.class);
public static void main(String[] args) {
int[] number = {10,20,30};
System.out.println("main number:" + Arrays.toString(number));
change(number);
System.out.println("change after main:" + Arrays.toString(number));
}
public static void change(int[] number) {
System.out.println("change number before" + Arrays.toString(number));
int[] number01 = {1,2,3};
number = number01;
System.out.println("change number after" + Arrays.toString(number));
}
}
main number:[10, 20, 30]
change number before[10, 20, 30]
change number after[1, 2, 3]
change after main:[10, 20, 30]
解析:main里面的number实参的引用地址值的内容没有发生改变,只是形参的副本地址值发生改变了。
3.例子三:
public class test {
private static final Logger logger = LoggerFactory.getLogger(test.class);
public static void main(String[] args) {
String number = "111";
change(number);
System.out.println("main:" + number);
}
public static void change(String number) {
System.out.println("change number before:" + number);
number = "222";
System.out.println("change number after:" + number);
}
}
change number before:111
change number after:222
main:111
解析:地址值对应的内容没发生变化,变的是副本地址值
例子四:
public class test {
private static final Logger logger = LoggerFactory.getLogger(test.class);
public static void main(String[] args) {
StringBuilder number = new StringBuilder("111");
StringBuilder number01 = new StringBuilder("111");
change(number, number01);
System.out.println("number:" + number); // 改变
System.out.println("number01:" + number01); // 不变
}
public static void change(StringBuilder number, StringBuilder number01) {
number.append("222"); // 对象的地址值不变,但是会在原地址值上改变对应的内容
number01 = new StringBuilder("222"); // 创建了新的对象
}
}
number:111222
number01:111
分析:number,地址值不变,但是内容变了,所以最好实参也发生改变了;number01地址值改变了,但是原来的地址值的内容不变,所以最后不变。
基本类型和包装类型的区别
基本类型:按值传递,默认值,不可判空,可变类,内存消耗偏小
包装类型:按引用传递,默认null,可判空。不可变类。内存消耗偏大