由java值传递与引用传递引出的一些

202 阅读2分钟

关于值传递与引用传递

Java中方法参数传递方式是按值传递。  
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。  
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。  
这是知乎上的一个回答,我认为这个解释还是比较容易接受的

基本数据类型

  • 基本数据类型: byte short int long double float char boolean
  • 引用类型: class interface array(数组)
当我在看Java的传递相关内容时,
我恰巧在回顾基本的排序算法,而排序中需要将两个比较的数据交换,即swap函数.
由于C/C++中有指针swap(int *a,int *b),则实现swap变得十分方便,
Java貌似好像没有这个功能啊,Java中只能通过引用变相地来实现

swap函数 Java实现(以int数组为例,list同理)

public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
}

(插一下)特殊的String类(不可变类)

  • String str = "ab"; //判断ab是否存在于字符串常量池中,若存在,直接返回引用;若不存在,则加入字符串常量池后再返回引用
  • String str = new String("ab"); //堆中
而我在网上浏览相关资料时,又发现了某些文章提到了jvm的内存模型,于是乎

JVM内存模型概览

虚拟机栈(线程私有,为Java方法提供内存空间)

  • 组成元素:栈帧
  • 当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,而帧是由局部变量区、操作数栈和帧数据区组成
这也就解释了Java是值传递还是引用传递,网上有的人说Java只有值传递
1. 如果只从栈帧的数据来看,Java确实只有值传递,基本数据类型传递值,对象传递其引用的值.
2. 但是从基本数据类型和对象的角度来看,Java的传递又是可以分为值传递与引用传递

  • 主要用于存放对象实例
  • 字符串常量池(jdk7之前存在于方法区)

方法区

  • 存放类信息、常量、静态变量、编译器编译后的代码等数据
  • 运行时常量池:是方法区的一部分,存放编译器生成的各种字面量和符号引用

程序计数器PC(线程私有)

  • 程序计数器PC,当前线程所执行的字节码行号指示器

本地方法栈(线程私有,为虚拟机使用到的Native方法提供内存空间)

参考

如有错误,望指正