众所周知Java的参数传递也分为值传递和引用传递
值传递
public class MethodAndParam { static void swap(int a,int b){ int c = a; a = b; b =c; } /** * @param args */ public static void main(String[] args) { int a = 1 ,b =2; swap(a, b); System.out.println(a+","+b); } }
其结果大家都知道,a、b的值没有交换成功。
引用传递
static void addA(StringBuffer sBuf){ sBuf.append("A"); } /** * @param args */ public static void main(String[] args) { StringBuffer sBuf = new StringBuffer(); addA(sBuf); System.out.println(sBuf.toString()); }
因为是引用传递,能找到对象的真实地址从而改变对象的值,其输出结果为A。
static void addA(String str){ str = str + "A"; } /** * @param args */ public static void main(String[] args) { String str = ""; addA(str); System.out.println(str); }
问题一:同样是引用传递,但结果并没有输出A,而是输出了空串,这是为什么呢?
我们将StringBuffer的例子改造如下:
static void addAByNew(StringBuffer sBuf){ sBuf = new StringBuffer(); sBuf.append("A"); } /** * @param args */ public static void main(String[] args) { StringBuffer sBuf = new StringBuffer(); addAByNew(sBuf); System.out.println(sBuf.toString()); }
同样上面的运行结果也没有输出A,而是输出了空串。如果传递的是引用,方法内部的代码sBuf = new StringBuffer()将引用指向了新的地址空间,在新的地址空间里append("A")。
问题二:在方法内部对引用的改变为什么没有影响到外部的对象?
对于问题一,大家可以看一下String对象的源码
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count;
String类是final修饰的,表示不能被继承。对于被final修饰的属性的赋值有如下几种方式:
1. 如果有static修饰的属性,可以在static{}块里赋值
2. 如果没有static修饰,可以在代码块{}里赋值
3. 在定义变量时赋值
4. 在构造方法里赋值
即一旦一个对象创建,其final修饰的属性值将不可改变,而String对象中存放值的value数组则是final修饰的,我们可以理解为:一个String对象的值改变后,它已经不是原来的它了。理解了String对象的不变性后可知问题一和问题二背后是同一个原因。
从JVM出发来看方法的调用
栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,每一个方法从调用开始到执行完成的过程,就对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
栈帧包括了局部变量表、方法返回地址等信息。其中局部变量表是一组变量值空间,用于存放方法参数和方法内部定义的局部变量。
现在可以回答问题二了:参数的引用传递不是单纯的将对象的引用传递给一个方法,而是将对象引用的地址传递给局部变量表里的参数引用,当在方法内部改变引用的地址时,只会影响方法内部的引用,而不会影响到方法外部的变量。但如果改变的是引用地址的值,方法内外的引用都会受影响。
相关推荐
NULL 博文链接:https://m635674608.iteye.com/blog/1513061
我们先看一下值传递和引用传递的概念和区别 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 引用传递:是指在调用函数时将实际参数的地址直接...
Java实验-掌握方法的声明和调用 掌握方法的值传递 掌握方法的重载
理解方法调用时值传递 方法调用时,需要提供实参,它们必须与方法签名中所对应的形参次序相同,这称作参数顺序匹配。 参数顺序匹配 public static void nPrintln(String message , int n){ for(int i = 0 ; i; i ++)...
然后自动产生代理类,但是在调用JAVA的WebService时并没有这么简单,特别是对于SoapHeader的处理,通过C#添加Web引用方式访问JavaWebService的方法,除了string类型能正常传递参数外,q其他类型的参数不是默认值就是...
简单webview嵌套html文件,原生和js互相调用方法,互相传递参数并打印都页面上
java调用远程接口传输数据的demo
读者将学习Java中方法调用时的参数传递方式,并重点探讨基本类型和引用类型在参数传递过程中的特点和区别。此外,我们还将介绍可变参数和返回值的使用方法。 能学到什么: 学习Java中方法调用时的参数传递方式。 ...
读者将学习Java中方法调用时的参数传递方式,并分别介绍基本类型和引用类型在参数传递过程中的特点和区别。 能学到什么: 学习Java中方法调用时的参数传递方式。 理解基本类型和引用类型在参数传递过程中的特点和...
lotus domino java代理_获取传递值json
java调用shell向DataX传递参数,where条件,包含特殊字符。java调用shell向DataX传递参数,where条件,包含特殊字符
II. java c/cpp互相调用实例(姊妹篇之一)——java调用c/cpp 4 一 先制作一个系统中有的DLL文件(cpp给出的sdk接口) 4 二 JNI 7 1、 编写java文件 7 2、 生成.h头文件 8 3、 用c/cpp实现这个头文件 9 三 测试 10 ...
java调用json参数的webservice 涉及技术: JAVA JSON WEBSERVICE
java调用shell 包含简单的编写shell文件 调用含有参数的shell文件
java中两种方式调用其他.exe可执行程序
Bartender提供了.net的开发sdk,但是没有提供java的,使得java开发者调用Bartender实现模板打印比较困难。本示例是结合Bartender官方资料,利用java通过COM组件方式实现可传递参数的模板打印。
JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...
通过对典型程序的研究与分析可以看出JAVA语言的参数传递总是传值调用的,但是对于基本类型的参数和对象类型的参数来说,参数传递的情况不完全相同.Java语言不能直接使用传引用调用,但是可以通过数组的方式模拟传引用...
Java语言后台实现调用url路径并传参。
函数调用参数传递类型(java)的用法介绍..ppt