我们都知道,在Java中,要领的参数通报永远都是指值通报。让我们来看一看根基范例和荟萃的参数通报在内存中是如何浮现的。
原文链接:https://dzone.com/articles/java-pass-by-reference-or-pass-by-value
在接头Java中参数是如何通报之前,我们有须要先弄清楚Java的变量(主要指的是根基范例和工具)是怎么存储在内存中的。
根基范例一般都存储在仓库中;对付Java工具,实际的工具数据存储在堆中,而工具的指针(指向推中的工具)存储在仓库中。
1.传值 vs 传引用
“传值”和“传引用”别离是什么意思:
2.在Java中参数是怎么通报的
在Java中,不管原始参数的范例是什么,参数都是按值通报的。每次当一个要领被执行的时候,劳务派遣管理系统,在仓库中就会为每个参数建设一个拷贝,这个拷贝会被通报到要领内部。
3.办理迷惑
在接下来的示例中,我们通过往要领中通报差异范例的参数(根基范例,昆山软件开发,包装类,荟萃类,自界说类),在要领执行完成后去查抄他们是否被修改了来实验证明“在Java中参数通报永远是值通报”。
根基范例参数
public static void main(String[] args) { int x = 1; int y = 2; System.out.print("Values of x & y before primitive modification: "); System.out.println(" x = " + x + " ; y = " + y ); modifyPrimitiveTypes(x,y); System.out.print("Values of x & y after primitive modification: "); System.out.println(" x = " + x + " ; y = " + y ); } private static void modifyPrimitiveTypes(int x, int y) { x = 5; y = 10; }
输出:
Values of x & y before primitive modification: x = 1 ; y = 2 Values of x & y after primitive modification: x = 1 ; y = 2
说明:
x,y这2个参数是根基范例,所以存储在仓库中。当挪用modifyPrimitiveTypes()要领时,在仓库中建设了这2个参数的拷贝(我们就叫它们w,z),实际上是w,z被通报到了要领中。所以原始的参数并没有被通报到要领中,在要领中的任何修改都只浸染于参数的拷贝w,z
包装类
public static void main(String[] args) { Integer obj1 = new Integer(1); Integer obj2 = new Integer(2); System.out.print("Values of obj1 & obj2 before wrapper modification: "); System.out.println("obj1 = " + obj1.intValue() + " ; obj2 = " + obj2.intValue()); modifyWrappers(obj1, obj2); System.out.print("Values of obj1 & obj2 after wrapper modification: "); System.out.println("obj1 = " + obj1.intValue() + " ; obj2 = " + obj2.intValue()); } private static void modifyWrappers(Integer x, Integer y) { x = new Integer(5); y = new Integer(10); }
输出:
Values of obj1 & obj2 before wrapper modification: obj1 = 1 ; obj2 = 2 Values of obj1 & obj2 after wrapper modification: obj1 = 1 ; obj2 = 2
说明:
包装类存储在堆中,在仓库中有一个指向它的引用
当挪用modifyWrappers()要领时,在仓库中为每个引用建设了一个拷贝,这些拷贝被通报到了要领里。任安在要领内里的修改都只是改变了引用的拷贝,昆山软件开发,而不是原始的引用
P.S: 假如要领中的表达式为x += 2,x值得改变也不会影响到要领外部,因为包装类是immutable范例的。当他们的state变革时,他们就会建设一个新的实例。假如你想相识更多关于immutable类,可以阅读How to create an immutable class in Java。字符串范例和包装类相似,所以以上的法则对付字符串也有效。
荟萃范例
public static void main(String[] args) { List<Integer> lstNums = new ArrayList<Integer>(); lstNums.add(1); System.out.println("Size of list before List modification = " + lstNums.size()); modifyList(lstNums); System.out.println("Size of list after List modification = " + lstNums.size()); } private static void modifyList(List<Integer> lstParam) { lstParam.add(2); }
输出:
Size of list before List modification = 1 Size of list after List modification = 2