zoukankan      html  css  js  c++  java
  • java中的值传递

    Java中只有值传递,没有引用传递。

    Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。 如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值. 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数(改变原来的值)。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

    1.当传递的是基本数据类型时,对基本数据类型的修改不会改变原始数据。

    2.当传递的是数组时,实际上传递的是数组的地址,数组的内容存在堆内存中。调用方法中修改了数组的内容时,原数组的内容也要改变的,因为调用方法修改了堆内存中数组的内容,而原始数组也是指向该地址的,引用没有改变,但是堆中值变了,所以原数组内容也就变了。。。对于这种问题最好画图分析,尤其是牵扯到引用也发生变化。

    如上代码,在调用方法中修改了数组的内容,原始数组内容也会发生变化。

    3:对于字符串而言,也是跟数组差不多,这里传递的是引用的一个副本。画内存图分析就好理解了。这里要注意String和StringBuilder的区别。下面以StringBuilder为例。

    public class Test {
    public static void main(String[] args) {
        StringBuffer a = new StringBuffer("A"); 
        StringBuffer b = new StringBuffer("B"); 
        operator(a, b); 
        System.out.println(a + "," + b); 
    public static void operator(StringBuffer x, StringBuffer y) { 
        x.append(y); y = x; 
    }
    }
    该代码的输出是AB,B....画内存图分析(牛客网上菜鸟葫芦娃的解析https://www.nowcoder.com/profile/7795492/myFollowings/detail/4420831)
    此时栈和堆内存中的状态如下图所示:
     
     
    publicstaticvoidoperator(StringBuffer x, StringBuffer y) { 
        x.append(y); y = x; 
    }
    进入如下方法后,内存中的状态为:
     
     
     x.append(y);
    这条语句执行后,内存的状态为:因为StringBuilder是可变的,所以是在原字符串上直接添加
     
     
     y = x; 
    这条语句执行后,内存的状态为:
     
     
    当operator方法执行完毕后内存中的状态为:因为方法执行完毕,局部变量消除。
     
    这个题,x是a引用的副本,但是x只是改变了内容,没有改变引用,所以a受影响。y是b引用的副本,y只改变了引用,所以b没有受影响。
     
    这里的数据结构如果是String,则a和b都不会发生变化,因为x+"B",这时会重新开辟空间,存放此AB变量,x指向AB,但是a指向不变,因为String是不可变的。
  • 相关阅读:
    C#6.0新语法
    C#泛型详解
    C#下Hashtable和Dictionary之间的差别
    C#中HashTable的用法
    MySQL日志
    MySQL创建数据表并建立主外键关系
    MySQL函数的使用
    MySQL实现SQL Server排名函数
    Windows安装SVN服务器和客户端
    Oracle SQL Developer 免费的DB2客户端
  • 原文地址:https://www.cnblogs.com/xiaolovewei/p/8075829.html
Copyright © 2011-2022 走看看