关于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交换一下, 看代码运行结果:
[img]http://dl2.iteye.com/upload/attachment/0122/2377/82f26fe8-441e-3482-9007-dbcb90fe5513.png[/img]
为了进行分析, 我直接在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;

}

}

运行结果:
[img]http://dl2.iteye.com/upload/attachment/0122/2379/7f3e1ecc-cf9a-37ab-b017-56a1841db2ae.png[/img]
运行结果是:x没有被改变值, 然后我在add()方法最后面增加x的输出:
[img]http://dl2.iteye.com/upload/attachment/0122/2381/ff0b2240-07eb-3a51-a149-e0ccae4cbfdc.png[/img]
用图例分析:
[img]http://dl2.iteye.com/upload/attachment/0122/2385/aa059762-1a13-3cc8-ace1-06d396bfcf85.png[/img]
其实在add()方法里面, 我们操作的是参数x的值的一个拷贝(注意这里是值的拷贝),即copy of x, 在方法里面操作的都是copy of x, 所以并不影响原来x的值.
[b]对于引用类型参数的传递, 的引用的拷贝.下面用图例分析开头的代码:[/b]
[img]http://dl2.iteye.com/upload/attachment/0122/2387/3e7067a4-8ce3-32de-8df9-28f686b05f8a.jpg[/img]
先说明下:如果对栈, 堆, 指针有些了解, 那么理解起来就很容易

从图例来看, 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值