一 值传递与引用传递接收
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,是有元素的。