这一次,彻底解决Java的值传递和引用传递

学过JAVA基础的人都知道:值传递和引用传递是初次接触Java时的一个难点 , 有时候记得了语法却记不得怎么实际运用 , 有时候会的了运用却解释不出原理 , 而且坊间讨论的话题又是充满争议:有的论坛帖子说Java只有值传递 , 有的博客说两者皆有;这让人有点摸不着头脑 , 下面我们就这个话题做一些探讨 , 对书籍、对论坛博客的说法 , 做一次考证 , 以得出信得过的答案 。
其实 , 对于值传递和引用传递的语法和运用 , 百度一下 , 就能出来可观的解释和例子数目 , 或许你看一下例子好像就懂 , 但是当你参加面试 , 做一道这个知识点的笔试题时感觉自己会 , 胸有成熟的写了答案 , 却发现是错的 , 或者是你根本不会做 。
是什么原因?
那是因为你对知识点没有了解透彻 , 只知道其皮毛 。要熟读一个语法很简单 , 要理解一行代码也不难 , 但是能把学过的知识融会贯通 , 串联起来理解 , 那就是非常难了 , 在此 , 关于值传递和引用传递 , 小编会从以前学过的基础知识开始 , 从内存模型开始 , 一步步的引出值传递和引用传递的本质原理 , 故篇幅较长 , 知识点较多 , 望读者多有包涵 。
1. 形参与实参我们先来重温一组语法:

形参:方法被调用时需要传递进来的参数 , 如:func(int a)中的a , 它只有在func被调用期间a才有意义 , 也就是会被分配内存空间 , 在方法func执行完成后 , a就会被销毁释放空间 , 也就是不存在了实参:方法被调用时是传入的实际值 , 它在方法被调用前就已经被初始化并且在方法被调用时传入 。
举个例子:
1public static void func(int a){2 a=20;3 System.out.println(a);4}5public static void main(String[] args) {6 int a=10;//实参7 func(a);8}例子中int a=10;中的a在被调用之前就已经创建并初始化 , 在调用func方法时 , 他被当做参数传入 , 所以这个a是实参 。而func(int a)中的a只有在func被调用时它的生命周期才开始 , 而在func调用结束之后 , 它也随之被JVM释放掉 ,  , 所以这个a是形参 。
2. Java的数据类型所谓数据类型 , 是编程语言中对内存的一种抽象表达方式 , 我们知道程序是由代码文件和静态资源组成 , 在程序被运行前 , 这些代码存在在硬盘里 , 程序开始运行 , 这些代码会被转成计算机能识别的内容放到内存中被执行 。因此
数据类型实质上是用来定义编程语言中相同类型的数据的存储形式 , 也就是决定了如何将代表这些值的位存储到计算机的内存中 。
所以 , 数据在内存中的存储 , 是根据数据类型来划定存储形式和存储位置的 。那么Java的数据类型有哪些?
基本类型:编程语言中内置的最小粒度的数据类型 。它包括四大类八种类型:
4种整数类型:byte、short、int、long2种浮点数类型:float、double1种字符类型:char1种布尔类型:boolean
引用类型:引用也叫句柄 , 引用类型 , 是编程语言中定义的在句柄中存放着实际内容所在地址的地址值的一种数据形式 。它主要包括:
类接口数组
有了数据类型 , JVM对程序数据的管理就规范化了 , 不同的数据类型 , 它的存储形式和位置是不一样的 , 要想知道JVM是怎么存储各种类型的数据 , 就得先了解JVM的内存划分以及每部分的职能 。
3.JVM内存的划分及职能Java语言本身是不能操作内存的 , 它的一切都是交给JVM来管理和控制的 , 因此Java内存区域的划分也就是JVM的区域划分 , 在说JVM的内存划分之前 , 我们先来看一下Java程序的执行过程 , 如下图:
这一次,彻底解决Java的值传递和引用传递

文章插图
 
1. 虚拟机栈2. 堆3. 程序计数器4. 方法区5. 本地方法栈【这一次,彻底解决Java的值传递和引用传递】我们接着来了解一下每部分的原理以及具体用来存储程序执行过程中的哪些数据 。


推荐阅读