zoukankan      html  css  js  c++  java
  • 值传递和引用传递

    值传递:传递的是实际参数的一个副本,这个值可能是基本类型,也可能是引用类型的地址.

    引用传递:传递的是实际参数的地址的一个副本.

    在java中,只有值传递.

    一.值传递

    1.基本类型

     1 public class ValueTest {
     2     
     3     public static void main(String[] args) {
     4         int a = 10;
     5         changeVal(a);
     6         System.out.println(a);
     7     }
     8     
     9     public static void changeVal(int a){
    10         a += 10;
    11     }
    12     
    13 }

    上面的demo输出的是10,而不是20。为什么?

    ①.程序运行时,main方法先入栈,然后给变量a分配内存。

    ②.当运行到changeVal(a);时,changeVal()方法入栈。当方法入栈时,会给局部变量和形参变量(a)分配内存.

       即在changeVal方法栈里面,也有一个名为a,值为10的变量。

    ③.由于a+=10;是在changeVal方法栈里面运行的,所以只会改变changeVal方法栈里面的a值,而不会改变main方法栈里面的a值。如下图

    2.引用类型

    引用类型也是值传递,不过这个"值"指的是对象的内存地址.

     1 public class ValueTest {
     2     
     3     public static void main(String[] args) {
     4         StringBuilder builder = new StringBuilder("hello");
     5         changeVal(builder);
     6         System.out.println(builder);
     7     }
     8     
     9     public static void changeVal(StringBuilder builder){
    10         builder.append(" world");
    11     }
    12     
    13 }

    输出是hello world,可见builder的值是改变了.

    与基本类型不一样,主要是StringBuilder是引用类型。因此new StringBuilder("hello")的内存是分配在堆区。而在栈区的变量(builder)只保存一个地址(假设为0x345),如下图:

    因此,main和changeVal两个方法栈的builder变量都指向了同一块内存。故当changVal方法中改变builder的值,main中的builder也会变化。

    3."特殊的"String

     1 public class ValueTest {
     2     
     3     public static void main(String[] args) {
     4         String str = "hello";
     5         changeVal(str);
     6         System.out.println(str);
     7     }
     8     
     9     public static void changeVal(String str){
    10         str+=" world";
    11     }
    12     
    13 }

    上面的demo输出的是:hello,而不是hello world。str记录了对象的地址,那么str的值应该也被改变了才对?

    这跟String的"特性"有关,String会被存放在字符串常量池,而且String是不可被改变的(final).

    ①.在第10行设个断点,当执行到这行的时候,由上面的分析可知,main()和changeVal()方法中的str都指向了常量池中的"hello"字符串。

    ②.执行str+=" world"时,由于String是不可变的,所以不可能直接在"hello"上做修改。这时会在常量池中新增一个"hello world"的字符串,并将地址传给changeVal()方法栈中的str.

    ③.因此changeVal()方法中的str指向了新增的"hello world"字符串,而main方法中的str还是指向原来的"hello"。所以输出"hello".

    二.引用传递

    引用传递,传递的是实际参数的地址.

    如下图,有变量builder,值指向了堆内存地址(假设为0x456)。但是builder变量本身也有地址(假设为0x123)。传递的时候,传的就是0x123.

  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/myCodingSky/p/3902284.html
Copyright © 2011-2022 走看看