关于Java中作用域和值传递的问题

之前在代码中刚好遇到过同样的问题, 现在我自己举个例子来大概描叙一下情况:
import java.util.*;

public class StringTest {

public static void main(String[] args) {

ArrayList list1 = new ArrayList();

list1.add("1");

ArrayList list2 = new ArrayList();

list2.add("2");

System.out.println("list1:" + list1.get(0));

System.out.println("list2:" + list2.get(0));

System.out.println("----------------");

swap(list1, list2);

System.out.println("After invoking swap()");

System.out.println("list1:" + list1.get(0));

System.out.println("list2:" + list2.get(0));

}

static void swap(List l1, List l2) {

List temp = l1;

l1 = l2;

l2 = temp;

System.out.println("------swap() begin-----");

System.out.println("l1:" + l1.get(0));

System.out.println("l2:" + l2.get(0));

System.out.println("------swap() end-----");

}

}

上诉例子中, 代码的意图是想着把list1 和 list2交换一下, 看代码运行结果:

为了进行分析, 我直接在swap()方法体中加了输出语句.

可以看出, 结果是list1 和 list2的引用并没有发生交换.

在我以前的知识中, 会讲到各种作用域阿, 局部参数等的问题, 其实对于当初新手的我来说要记住这些东西是很麻烦的....在我接触到 值传递和引用传递这两个概念以及了解到java语言中是值传递的, 我就瞬间明白了上述运行结果中没有发生交换的原因.

值传递概念:表示方法接收的是调用者提供的值.得到的是参数值的一个拷贝.(这里概念来自于Core Java 卷一 第九版 方法参数这章)

首先, 用基本数据类型来解释下这个 值传递的概念:
public class CopyTest {

public static void main(String[] args) {

int x = 10;

System.out.println(x);

add(x);

System.out.println("After add()");

System.out.println(x);

}

static void add(int x) {

x += 10;

}

}

运行结果:

运行结果是:x没有被改变值, 然后我在add()方法最后面增加x的输出:

用图例分析:

其实在add()方法里面, 我们操作的是参数x的值的一个拷贝(注意这里是值的拷贝),即copy of x, 在方法里面操作的都是copy of x, 所以并不影响原来x的值.
对于引用类型参数的传递, 的引用的拷贝.下面用图例分析开头的代码:

先说明下:如果对栈, 堆, 指针有些了解, 那么理解起来就很容易

从图例来看, swap()方法里面获取得其实是来自于list1和list2的拷贝, 拷贝的是list1(0x00)内存块里面的值(0x10), 并不是把(0x00)传过去(其实这种就是引用传递).list2和l2也是同理

因此当l1  和 l2互换的时候, 换的是0x02 和 0x03内存块里面的内容, 所以在swap()方法里面是, l1 和 l2 是已经发生交换了, 但是外部的list1 和 list2 并没有发生任何影响.

这里额外提一点, 假设swap()方法如下:
static void (List l1, List l2) {

l1.add("a");
l2.add("b");

}

那么外部的list1 和 list2肯定各自增加了"a", "b", 因为这里的l1 和 list1 指向的实例都是一样的.即l1 和 list1 对应的内存块里面存的值都是0x10. l2 和 list2也是同理.
如果不明白的话可以手动敲一下代码, 然后画图理解, 最重要的是稍微理解堆, 栈, 和java中关于指针的知识就行啦.
若有不对的地方, 请指正~thx

猜你喜欢

转载自cloudgan.iteye.com/blog/2347618
今日推荐