Java是一门面向对象的程序设计语言,类是其基本抽象单元,而方法是类中可复用的执行单元;当一个Java方法被调用,方法参数的传递方式究竟是基于值传递
还是引用传递
呢?答案是:值传递 !
1. 基础知识回顾
1.1 形参(formal parameter)与实参(actual parameter)
1.2 值传递(pass by value)与引用传递(pass by reference)
通常,在编程语言中关于方法参数的传递主要有两种方式:
-
在值传递中,
Callee
方法内访问的是Caller
方法中的实参的拷贝副本,故而对Caller
中的实参没有影响; -
在引用传递中,
Caller
方法中实参所持有的内存地址会直接传递给Callee
方法,故而在Callee
方法中可以影响Caller
中的实参。
值传递与引用传递的根本区别在于操作的是同一块内存还是新开辟了一块内存;直白点说,值传递涉及新开辟一块内存区域。
1.3 虚拟机栈(jvm stack)
Java虚拟机栈
是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是线程上下文中方法执行的内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧
(Stack Frame) 用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。特别地,Java方法内的局部变量即存放于引用变量表中,对于基本类型 (primitive type),直接存储值;对于引用类型 (reference type),存储的是对象在堆内存中的内存地址值,比如0x604950490
,内存地址值并不等同于对象本身。
2. 回归正题
既然Java中只有两种数据类型,那下面就以这两种数据类型为维度来剖析Java中方法参数的值传递原理。
2.1 基本数据类型
public class PassByValueMain1 {
public static void main(String[] args) {
int i = 10086;
System.out.println(i);
method(i);
System.out.println(i);
}
private static void method(int j) {
j = 10000;
}
}
运行结果
10086
10086
运行原理
2.2 引用数据类型
public class PassByValueMain2 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("hello");
System.out.println(sb);
method(sb);
System.out.println(sb);
}
private static void method(StringBuilder _sb) {
_sb.append(", world");
}
}
运行结果
hello
hello, world
运行原理
3 总结
-
Java中方法参数的传递方式是基于值传递的; -
如果参数是基本类型,传递的是基本类型的字面量值的拷贝; -
如果参数是引用类型,传递的是该参数所引用的对象在堆内存中地址值的拷贝; -
值传递始终会新开辟一块内存区域。
原文始发于微信公众号(程序猿杜小头):图说Java值传递原理
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222316.html