java的值传递和引用传递

java基本数据类型:byte、short、int、long、float、double、char、boolean
引用类型:String、集合类、自定义对象

java的值传递和引用传递可以分三种情况讨论:

  • 基本数据类型:是值传递。内存来说,基本数据类型的值是存放在栈空间,作为方法形参时,这个变量和值会被复制出一份,在此方法栈中对该变量的改变不会对其他方法栈的变量产生任何影响。
  • 引用类型:引用传递。引用类型的值是对象,存放在堆空间中,作为方法形参时,在栈空间中复制了一个变量副本,值传递的是该对象的内存地址,而方法中的变量相当于方法栈中指向堆内存的一个指针。
    直接对变量赋值相当于是改变指针的指向,而对应内存地址里面的值并没有改变,所以上层方法变量指向的对象不会改变。
    但是,如果对内存地址里面的值进行了赋值,就是改变了堆内存对象本身的值了,上层方法变量指向的对象本身的值就不一样了。
  • 引用类型特例:String。String是final类型的,也就是不可变类型。
    作为方法形参时,跟引用类型一样,都是通过指针变量副本指向内存地址。
    如果在方法内赋予新的值时,其实是在堆内存创建了新的对象,并将指针变量指向了新对象的内存地址。

代码示例

  1. 基本数据类型:值传递
//基本数据类型:是值传递。内存来说,基本数据类型的值是存放在栈空间,作为方法形参时,这个变量和值会被复制出一份,在此方法栈中对该变量的改变不会对其他方法栈的变量产生任何影响。
public static void swap(int num1,int num2) {
int temp = num1;
num1 = num2;
num2 = temp;
System.out.println("a="+num1);
System.out.println("b="+num2);
}

public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("---交换后---");
swap(a,b);
System.out.println("---原有的----");
System.out.println("a="+a);
System.out.println("b="+b);
}

结果:

---交换后---
a=20
b=10
---原有的----
a=10
b=20
  1. 引用类型:引用传递
static class Node{
String name;
Integer score;

Node(String name) {
this.name = name;
}

@Override
public String toString() {
return "name:"+name+",score:"+score;
}
}
//引用类型:引用传递。引用类型的值是对象,存放在堆空间中,作为方法形参时,在栈空间中复制了一个变量副本,值传递的是该对象的内存地址,而方法中的变量相当于方法栈中指向堆内存的一个指针。
// 直接对变量赋值相当于是改变指针的指向,而对应内存地址里面的值并没有改变,所以上层方法变量指向的对象不会改变。
// 但是,如果对内存地址里面的值进行了赋值,就是改变了堆内存对象本身的值了,上层方法变量指向的对象本身的值就不一样了。
public static void swap2(Node node1,Node node2){
Node temp = node1;
node1 = node2;
node2 = temp;
node1.name = "ddd";
node1.score = 10;
System.out.println("node1="+node1);
System.out.println("node2="+node2);
}

public static void main(String[] args) {
Node node1 = new Node("a");
Node node2 = new Node("b");
System.out.println("----交换后--------");
swap2(node1,node2);
System.out.println("-----原有的-------");
System.out.println("node1="+node1);
System.out.println("node2="+node2);
}

结果:

----交换后--------
node1=name:ddd,score:10
node2=name:a,score:null
-----原有的-------
node1=name:a,score:null
node2=name:ddd,score:10
  1. 引用类型特例:String
//引用类型特例:String。String是final类型的,也就是不可变类型,作为方法形参时,跟引用类型一样,都是通过指针变量副本指向内存地址。
//而如果在方法内赋予新的值时,其实是在堆内存创建了新的对象,并将指针变量指向了新对象的内存地址。
public static void swap3(String str1,String str2){

String temp = str1;
str1 = str2;
str2 = temp;
str1 = "ccc";
System.out.println("str1内存地址:"+str1.hashCode());
System.out.println("str2内存地址:"+str2.hashCode());
System.out.println("str1="+str1);
System.out.println("str2="+str2);
}

public static void main(String[] args) {
String str1 = "aaa";
String str2 = "bbb";
System.out.println("str1内存地址:"+str1.hashCode());
System.out.println("str2内存地址:"+str2.hashCode());
System.out.println("---交换后---");
swap3(str1,str2);
System.out.println("----原有的-----");
System.out.println("str1="+str1);
System.out.println("str2="+str2);
}

结果:

str1内存地址:96321
str2内存地址:97314
---交换后---
str1内存地址:98307
str2内存地址:96321
str1=ccc
str2=aaa
----原有的-----
str1=aaa
str2=bbb
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值