美文网首页
[Java]按值传递/按引用传递?

[Java]按值传递/按引用传递?

作者: __Liu__ | 来源:发表于2017-01-09 17:25 被阅读0次

先上一段代码

public class SimpleTest {
    
    String str ="good";
    char[] ch = {'a','b','c'};
    
    public void change(String str,char ch[]){
        str = "test ok";
        ch[0] = 'g';
    }
    
    public static void main(String[] args) {
        SimpleTest st = new SimpleTest();
        st.change(st.str, st.ch);
        System.out.print(st.str + " and ");
        System.out.print(st.ch);
    }
}
PS: 字符串一旦创建,便不可修改
PPS: JVM内存可分为三个区,堆(Heap),栈(Stack),方法区(Method)

堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身

栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。


这段代码都做了些什么
1.启动一个JVM进程,首先从classpath找到SimpleTest.class文件,读取文件中的二进制数据,然后把SimpleTest类的类信息存放在运行时数据区的方法区中,这一过程称为SimpleTest的类加载过程
2.JVM定位到方法区中SimpleTest类的main()方法的字节码,开始执行它的指令。第一条语句是:
SimpleTest st = new SimpleTest();
语句很简单啦,就是让JVM创建一个SimpleTest实例,并且,使引用变量st来引用这个实例。看起来是小事一桩,具体JVM是怎么执行的呢?
1> 不就是建立一个SimpleTest实力吗?JVM直奔方法区,先找到SimpleTest类的类信息再说。结果呢//木有@_@,这会儿的方法区内还没有SimpleTest类。可JVM也不蠢...“自己动手,丰衣足食”,立马加载了SimpleTest类,并把类信息存放在方法区里。
2>类信息有了,JVM第一件事就是在堆内为一个新的SimpleTest实例分配内存,这个SimpleTest实例持有着指向方法区中的内存地址,这个地址,就存放在了SimpleTest实力的数据区。
3>在JVM进程中,每个进程都会拥有一个方法调用栈,用来跟踪线程运行中一系列的方法调用过程,栈中的每一个元素就被称为栈帧,每当线程调用一个方法的时候就会向方法栈压入一个新帧,用来存储方法的参数,局部变量和运算过程中的临时数据。位于“=”前的st是一个在main()方法中定义的变量,可见他是一个局部变量,因此它会被添加到执行了main()方法的主线程的JAVA方法调用栈中。而“=”将把这个st变量指向堆区中的SimpleTest实例,也就是说,它持有指向SimpleTest实例的引用。
到这里,第一条语句就执行完了。
3.接着就是调用st引用的对象的change方法,并把st所引用的字符串str和字符数组ch传入change方法,以一个新帧被压入change()方法所在的主线程的栈区。
4.在change()方法所在的栈区,st.str被要求引用"test ok"所在内存的地址,注意到上面提及的,“字符串一旦创建,便不可修改”,便是在main()方法所在的栈区内,st.str始终是引用了"good"所在的地址,在change()方法所在的栈区内,想改变st.str的引用为"test ok",实际上是重新开辟了另一块内存存放"test ok",并将此时的st.str暂时指向"test ok",我们可以在两处str和ch分别输出他们的hashcode。
引用变量时,除了8个基本类型外(byte,short,int,long,float,double,char,boolean),都是传递的内存地址,包括数组。所以这里的char数组ch[],是st.ch所开辟出来的内存地址,被要求ch[0]重新指向字符'g'。
到此,change()方法结束。
5.回到main()方法,st.str仍然指向"good",但ch[0]指向了'g'。
输出 good and gbc

Java没有按引用传递,全部是按值传递,传的是内存地址

jvm.png

相关文章

  • 聊聊Java内部类

    一.磨叽磨叽Java值传递与引用传递 “在Java里面参数传递都是按值传递”即:按值传递是传递的值的拷贝,按引用传...

  • Java值传递

    “在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值...

  • [Java]按值传递/按引用传递?

    先上一段代码 PS: 字符串一旦创建,便不可修改 PPS: JVM内存可分为三个区,堆(Heap),栈(Stack...

  • JS是按值传递还是按引用传递?

    JS是按值传递还是按引用传递? 按值传递 VS. 按引用传递 探究JS值的传递方式 按共享传递 call by s...

  • Java中的参数传递

    为了便于理解,会将参数传递分为按值传递和按引用传递。按值传递是传递的值的拷贝,按引用传递传递的是引用的地址值,所以...

  • Java调用方法时值传递的理解

    Java中方法调用时,没有按引用传递这个说法,只有按值传递。基本类型数据的传递和引用类型数据的传递,根本上都是按值...

  • 再学JS--函数参数传递类型

    JavaScript的函数参数传递分为按值传递、按引用传递以及按共享传递。 按值传递 什么是按值传递? 把函数外部...

  • 按值传递、按引用传递、按共享传递

    按值传递、按引用传递、按共享传递 按值传递(call by value) 按值传递,就是指在调用函数时,将实参对应...

  • Java 参数的传递

    Java 的参数是值传递,不是引用传递 Java 中只有值传递,方法按值调用(call by value)。也就是...

  • 方法参数

    一、参数传递 1.参数传递有两种类型:按值传递和按引用传递。 2.按值传递指变量使用的是参数传递的值,而按引用传递...

网友评论

      本文标题:[Java]按值传递/按引用传递?

      本文链接:https://www.haomeiwen.com/subject/xfthbttx.html