博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
值传递和引用传递
阅读量:4678 次
发布时间:2019-06-09

本文共 2027 字,大约阅读时间需要 6 分钟。

值传递:传递的是实际参数的一个副本,这个值可能是基本类型,也可能是引用类型的地址.

引用传递:传递的是实际参数的地址的一个副本.

在java中,只有值传递.

一.值传递

1.基本类型

1 public class ValueTest { 2      3     public static void main(String[] args) { 4         int a = 10; 5         changeVal(a); 6         System.out.println(a); 7     } 8      9     public static void changeVal(int a){10         a += 10;11     }12     13 }

上面的demo输出的是10,而不是20。为什么?

①.程序运行时,main方法先入栈,然后给变量a分配内存。

②.当运行到changeVal(a);时,changeVal()方法入栈。当方法入栈时,会给局部变量和形参变量(a)分配内存.

   即在changeVal方法栈里面,也有一个名为a,值为10的变量。

③.由于a+=10;是在changeVal方法栈里面运行的,所以只会改变changeVal方法栈里面的a值,而不会改变main方法栈里面的a值。如下图

 

2.引用类型

引用类型也是值传递,不过这个"值"指的是对象的内存地址.

1 public class ValueTest { 2      3     public static void main(String[] args) { 4         StringBuilder builder = new StringBuilder("hello"); 5         changeVal(builder); 6         System.out.println(builder); 7     } 8      9     public static void changeVal(StringBuilder builder){10         builder.append(" world");11     }12     13 }

输出是hello world,可见builder的值是改变了.

与基本类型不一样,主要是StringBuilder是引用类型。因此new StringBuilder("hello")的内存是分配在堆区。而在栈区的变量(builder)只保存一个地址(假设为0x345),如下图:

因此,main和changeVal两个方法栈的builder变量都指向了同一块内存。故当changVal方法中改变builder的值,main中的builder也会变化。

 

3."特殊的"String

1 public class ValueTest { 2      3     public static void main(String[] args) { 4         String str = "hello"; 5         changeVal(str); 6         System.out.println(str); 7     } 8      9     public static void changeVal(String str){10         str+=" world";11     }12     13 }

上面的demo输出的是:hello,而不是hello world。str记录了对象的地址,那么str的值应该也被改变了才对?

这跟String的"特性"有关,String会被存放在字符串常量池,而且String是不可被改变的(final).

①.在第10行设个断点,当执行到这行的时候,由上面的分析可知,main()和changeVal()方法中的str都指向了常量池中的"hello"字符串。

②.执行str+=" world"时,由于String是不可变的,所以不可能直接在"hello"上做修改。这时会在常量池中新增一个"hello world"的字符串,并将地址传给changeVal()方法栈中的str.

③.因此changeVal()方法中的str指向了新增的"hello world"字符串,而main方法中的str还是指向原来的"hello"。所以输出"hello".

 

二.引用传递

引用传递,传递的是实际参数的地址.

如下图,有变量builder,值指向了堆内存地址(假设为0x456)。但是builder变量本身也有地址(假设为0x123)。传递的时候,传的就是0x123.

转载于:https://www.cnblogs.com/myCodingSky/p/3902284.html

你可能感兴趣的文章
Java中int类型和tyte[]之间转换及byte[]合并
查看>>
silverlight2 游戏 1 你能坚持多少秒
查看>>
数组元素java集合源代码分析(一)
查看>>
一边学习一边爱着梦着一边生活
查看>>
线性结构与非线性结构
查看>>
ID:12031 全排列
查看>>
SpringMVC注解版前台向后台传值的两种方式(IDEA)
查看>>
从Google Earth 中下载三维模型
查看>>
java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition的解决方案
查看>>
柔性数组(用于结构体)
查看>>
讲解下for循环的用法,加深记忆
查看>>
使用Spring.Net
查看>>
002-BootStrap基本模板
查看>>
HttpClient使用详细教程
查看>>
Python黑科技:赋值技巧
查看>>
mybatis insert前获取要插入的值
查看>>
OGRE 入门 一、 ubuntu 12.04 下编译
查看>>
MySQL按照汉字的拼音排序
查看>>
3.1.3自适应阈值化
查看>>
NABCD
查看>>