最近的一个项目,里面各种返回void,参数用引用类型,那叫一个熟和多,但是也把我绕糊涂了。

我就打算好好理一理java的传参机制,整理一番

很多人一听Java的传参,那一定会脱口而出,java都是值传递的。恭喜各位,答对了。

那么,传的是什么值?

如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.

如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。
 
 

这里我给个代码就很好理解了
 public class ParamterTest {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
list1.add(0);
list2.add(0); //(1)
f(list1, list2);
System.out.println("list1 2");
p(list1);
System.out.println("list2 2");
p(list2); //(4)
} public static void f(List<Integer> list1, List<Integer> list2) {
list1.add(1);
list2.add(1);
list2 = new ArrayList<>(); //(2)
list1.add(2);
list2.add(2);
System.out.println("list1 1");
p(list1);
System.out.println("list2 1");
p(list2); //(3)
} public static void p(List<Integer> list) {
for (Integer i : list) {
System.out.println(i);
}
}
}

输出结果

list1 1
0
1
2
list2 1
2
list1 2
0
1
2
list2 2
0
1

要具体解释,就是涉及到堆,栈和方法区了。

(1)list1,list2刚刚成立,都放进了 0,因为是对象的实例所以保存在堆里面。

(2)list1,list2将自己堆的地址传到了方法里,因为是引用所以保存在栈里面,并通过地址往堆里面的实例,放进了 1。但是,此时new了一个实例,list2在栈里面不再指向堆的实例,而是一个新的地址。

(3)list1,list2放进了2,但此处list1依然指向堆的实例,故放进了 2,而list2则是新的地址,堆的list2并没有放进 2。

(4)方法结束,返回的结果使堆的list1,放进了 1 , 2 。list2 因为在方法内中途有新的实例, 只放进了 1 ,而没有 2。

其实一直迷惑我们,是我们判断出错的是String ,明明是一个引用类型,却是基本类型的特性,因为String 实际上是[]char,具体不细说,我就丢个代码,让大家跑跑吧。

public class ParamterStringTest {
public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
f(s1, s2);
System.out.println("s1 2");
p(s1);
System.out.println("s2 2");
p(s2);
} public static void f(String s1, String s2) {
s1 = "b";
s2 = "b";
System.out.println("s1 1");
p(s1);
System.out.println("s2 1");
p(s2);
} public static void p(String s) {
System.out.println(s);
} }

同理,相应的Interge等包装类。

Java函数的传参机制的更多相关文章

  1. Java的对象传参问题

    在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.之前有搜过相关的知识点一直理解的是:Java的传参方式中主要有两种: ...

  2. java复用和传参

    java复用和传参的三种方法总结: (1) 直接在一个类中调用函数 : 1 package test1; 2 3 public class a 4 { 5 public static void get ...

  3. uboot向kernel的传参机制——bootm与tags

    http://blog.csdn.net/skyflying2012/article/details/35787971 最近阅读代码学习了uboot boot kernel的过程以及uboot如何传参 ...

  4. C#为什么不能像C/C++一样的支持函数只读传参

    C#为什么不能像C/C++一样的支持函数只读传参? 这个问题其实问的人挺多的,我自己也经常想实现这个功能,但是发现总是那么的不尽人意. 有些人倒是给出了一下答案,但是都不能很好的解决像C/C++一样的 ...

  5. Python全栈工程师(函数的传参)

     ParisGabriel   感谢 大家的支持                                                               每天坚持 一天一篇 点个订 ...

  6. C# PDF Page操作——设置页面切换按钮 C# 添加、读取Word脚注尾注 C#为什么不能像C/C++一样的支持函数只读传参 web 给大家分享一个好玩的东西,也许你那块就用的到

    C# PDF Page操作——设置页面切换按钮   概述 在以下示例中,将介绍在PDF文档页面设置页面切换按钮的方法.示例中将页面切换按钮的添加分为了两种情况,一种是设置按钮跳转到首页.下页.上页或者 ...

  7. Python之函数(一)定义函数以及传参

    定义函数以及传参 函数的定义 def 函数名(): 函数体 例子: def func():#def关键字--定义 func函数名--和变量定义规则一样 ()必须要写格式 :声明 语句结束 s=[1,2 ...

  8. 『Python &#215; C++』函数传参机制学习以及对比

    一.Python函数传参 在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么 ...

  9. 在Java中动态传参调用Python脚本

    最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称 ...

随机推荐

  1. scikit-learn算法选择图

    图片来自sklearn官网 最近事情弄完一部分了,继续开始python data science!

  2. Atitit sql计划任务与查询优化器--统计信息模块

    Atitit sql计划任务与查询优化器--统计信息模块 每一个统计信息的内容都包含以上三部分的内容. 我们依次来分析下,通过这三部分内容SQL Server如何了解该列数据的内容分布的. a.统计信 ...

  3. Grunt 安装与配置环境

    当时学习 Grunt 的时候,真是很头疼.分了两个时间段,学习了两次才硬啃下来,之后才能用在项目中.主要原因我认为是学习资料和文档上面写的太高端了.这类的文档或者资料有个显著特点,上来先简单介绍一下这 ...

  4. Linux下pipe使用注意事项

    转自:http://blog.yufeng.info/archives/1485 Linux下的pipe使用非常广泛, shell本身就大量用pipe来粘合生产者和消费者的. 我们的服务器程序通常会用 ...

  5. java io 输入输出流

    数据流分类: 流序列中的数据既可以是未经加工的原始二进制数据, 也可以是经一定编码处理后符合某种格式规定的特定数据. 因此Java中的流分为两种: 1) 字节流:数据流中最小的数据单元是字节 2) 字 ...

  6. switchover步骤切换

    主库 alter system switch logfile; alter system set log_archive_dest_state_2='defer'; select switchover ...

  7. 编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数 wheels和车重weight。小车类Car是Vehicle的子类,其中包含的属性有载人数 loader。卡车类Truck是Car类的子类,其中包含的属性有载重量payload。每个 类都有构造方法和输出相关数据的方法。最后,写一个测试类来测试这些类的功 能。

    package car; public class Vehicle { //定义成员变量 private int wheels; private double weight; public int g ...

  8. eclipse手动添加源码

    在开发过程中,有的时候需要我们自已手动去添加一些源码文件,但是由于我们可能在eclipse中安装了jad反编译插件,我们再用“Ctrl + 鼠标左键”的话,会打开已经反编译好的class文件,而不是带 ...

  9. Java学习之开篇—个人随想

    现在大三上学期了,家里希望考研,不然觉得我这学校不好找工作,我自己觉得工作还是靠自己,学校就像给人第一眼感觉那样,虽然重要但也只会吸引HR多看两眼,真正留得住HR的还是要有拿的出手的技能. 当初凭着对 ...

  10. linux_shell_轮询触发启动脚本

    while [ 1 ]do length=`redis-cli -h *.*.*.* -p 8000 llen eq` while [ $length -gt 1 ] do echo "le ...