zl程序教程

您现在的位置是:首页 >  后端

当前栏目

java中值传递和引用传递案例剖析

JAVA案例 引用 剖析 传递 中值
2023-09-27 14:22:12 时间

一  值传递与引用传递接收

1.1Java的数据类型:

基本数据类型:byte short int long double float boolean char

引用数据类型:类类型,接口,数组

1.2 java传递类型介绍

1.2.1.数据传递

值类型默认存放在栈中,但当值类型是在引用类型中声明的时候,则存放在其所在的引用类型的堆中。

1.2.2 值传递

值传递:在方法调用时,实参将它的值通过复制一份给形参,形参相当于实参的副本,方法中业务逻辑对形参的操作,对实参的值没有影响。

此时内存中存在两个相等的基本类型,即实际参数和形式参数

1.2.3 引用传递

引用类型存放在堆中。其在堆中的内存地址存放在栈中

在方法调用时,实参将引用地址(,而不是参数的值传递给形参,形参接受实参的内存地址,在方法中,形参和实参通过引用地址都指向堆中同一个实际的数据对象

业务对形参的操作,对实参的值有影响

这里要特殊考虑String,以及Integer、Double等几个基本类型包装类,它们都是immutable类型,
因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待,可以认为是和基本数据类型相似,传值操作

 

 https://www.cnblogs.com/David-Huang/p/5127821.html 

http://www.cnblogs.com/binyue/p/3862276.html

1.3 操作案例

1.3.1 案例1

public class App 
{
    public static String s="nihao";
    public static void main( String[] args )
    {
      String str="hello";
      char[] ch=new char[]{'a'};
      int i=1;
      List<String > list=new ArrayList<String>();
      list.add("liu");
      transfer(str,ch ,i,list);
      System.out.println("str:"+str);
      System.out.println("ch:"+ch[0]);
      System.out.println("i:"+i);
      System.out.println("s:"+s);
      System.out.println("list:"+list.toString());
    }
    public static void transfer(String str,char [] ch,int i,List<String > list){
        str="world";
        s="world";
        ch[0]='b';
        i=2;
        list.add("jian");
    }
}

结果:

str:hello
ch:b
i:1
s:world
list:[liu, jian]

1.3.2 案例2

public class Test {
    public static void main(String[] args) {
        List<String> dataList=new ArrayList<>();
        getList( dataList);
        dataList.forEach((x)->{System.out.println("x:"+x);});
    }
    public static void getList(List<String> dataList){

        List<String> benaList=new ArrayList<>();
        System.out.println("dataList:"+dataList.hashCode()+" beanList:"+benaList.hashCode());
        benaList.add("ljf");
        System.out.println("dataList:"+dataList.hashCode()+" beanList:"+benaList.hashCode());
        dataList=benaList;
      // dataList.addAll(benaList);
        System.out.println("dataList:"+dataList.hashCode()+" beanList:"+benaList.hashCode());
    }
}

结果: 没有数据,只是查看打印,两个集合的hashcode的变化。为何listA引用数据类型作为调用方法的参数,在方法中新集合listB有值,且赋值给listA,在方法外调用ListA,居然没有数据呢?

 分析原因:

情况1:直接listB赋值listA,只是栈中的内存地址发生变化;

情况2:listB将内存地址和结合元素全部赋值给ListA,此时访问ListA,是有元素的。