数组作为方法参数的一个问题。

tequliapop 2009-12-01 05:39:59
把数组作为参数传入一个方法。在该方法中对数组进行一些操作:如果仅仅是插入数据项等一般操作,那么该操作会影响到数组本身;反之,如调整数组大小、对数组赋值等操作,则对数组本身没有影响。

各位TX,请问其中的原理是什么喃?

附一个例子:
public class Tester {
public static void counter(int count) {
count = 2;
}

public static void changeA1(int[] ints) {
int[] temp = { 4, 5, 6 };
ints = temp;
}

public static void changeA2(int[] ints) {
ints[0] = 4;
ints[1] = 5;
ints[2] = 6;
}

public static void main(String[] args) {
// Output: 1
// 基本数据类型没有改变。
int count = 1;
counter(count);
System.out.println("count: " + count);


int[] ints = { 1, 2, 3 };

// Output: 1, 2, 3
// 对数组赋值,不会改变原始数组。
changeA1(ints);
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i] + " ");
}

// Output: 4, 5, 6
// 可以对数组插入新的数据项。
System.out.println();
changeA2(ints);
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i] + " ");
}
}
}
...全文
617 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kav3000 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
楼主这个问题不错啊!我想了一下,感觉还是用一个形象的故事来讲比较容易理解。

楼主这个问题可以归结为传值和传引用的区别问题。

下面开讲故事:

从前有个房间,房间里有份文档,房间还有一把钥匙。 这把钥匙在张三手里。

这时李四来向张三要那份文档。 张三不太喜欢李四,但又怕耽误了
工作不好交代。于是张三就把房间里文档的文档复印了一份,然后把那个复印件交给了李四(这叫传值)。……
[/Quote]
很有趣的解说!真的是学习了数组的相关内容!
lewisonchen 2012-05-13
  • 打赏
  • 举报
回复
有疑问的可以去看看《core java》第一卷116页。。。。里面讲的很清楚,6楼跟17楼正确。其他所有说是传引用的全部错误。
forestM 2012-03-16
  • 打赏
  • 举报
回复
java2核心技术第7版第1卷116页:Java程序设计语言对对象采用的不是引用调用,实际上,对象引用进行的是值传递。

counter()不解释

在函数changeA1()内部数组ints[]与数组temp[]的首地址确实交换了,但是这种交换属于值交换,也就是说退出这个函数体后,数组temp[]会被释放,而ints依然是原来的地址

changeA2()相当于对数组里每个元素进行赋值操作。
jichunweistar 2009-12-10
  • 打赏
  • 举报
回复
经典老问题,值得学习,实际上传值和传引用看你自己怎么理解。个人认为还是认为传值的好,都看作是值的副本。
whereusejava 2009-12-03
  • 打赏
  • 举报
回复
所有的参数传递都是值传递!对象的引用本身就是“值”
heartraid86 2009-12-03
  • 打赏
  • 举报
回复
首先:数组也是对象。数组名就是对象引用

然后:可以看看我写的一篇博客《引用调用还是值调用? ——Java陷阱》
AiJingYuan 2009-12-03
  • 打赏
  • 举报
回复
数组作为参数传递时,是引用传递,实际上这个Java存储变量有一点的联系,如果是值类型的, 在栈中存储的是包含的值,如果是引用类型的,在栈中存储的是引用地址,实际上传参时,传递的都是栈中存储的东西,只不过因为值类型和引用类型在栈中存储的东西不一样罢了,你传递数组时,在方法中改变了改数组的引用,而在外面是接受不到的,因为Java不支持在方法中更改变量的引用地址,创建新的引用,所以在方法执行后,同样没有能够输出改变后的数组中的内容,而改变数组中的元素,并没有改变该数组的变量的整个引用,所以在方法执行后,保存的是更改后的数组


--嘿嘿--我也就知道这么多,献丑了!!!
xinqiou 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 islandrabbit 的回复:]
楼主这个问题不错啊!我想了一下,感觉还是用一个形象的故事来讲比较容易理解。

楼主这个问题可以归结为传值和传引用的区别问题。

下面开讲故事:

    从前有个房间,房间里有份文档,房间还有一把钥匙。 这把钥匙在张三手里。

这时李四来向张三要那份文档。 张三不太喜欢李四,但又怕耽误了
工作不好交代。于是张三就把房间里文档的文档复印了一份,然后把那个复印件交给了李四(这叫传值)。

李四拿到文档后(复印件),胡乱修改一番,心想:张三,这回要你好看。可是他没想到那份原件还好好的在张三的房间里锁着呢。

以上故事对应:
public static void counter(int count) {
count = 2;
}

这个李四不甘心,于是他偷偷地配了一把张三的钥匙(这叫传引用), 准备进入房间修改那份文档。
这事被张三及时发现,他悄悄的把李四配的钥匙换成了另外一个房间的钥匙。
李四去了错误的房间。 张三再次以胜利告终!

    以上故事对应:
public static void changeA1(int[] ints) {
int[] temp = new int[3];
ints = temp;

ints[0] = 7;
ints[1] = 8;
ints[2] = 9;
}

李四锲而不舍,他趁张三还沉浸两次胜利的喜悦里,终于成功的配了钥匙(这叫传引用),达到了修改那份文档原件的目的。
以上故事对应:
public static void changeA2(int[] ints) {
ints[0] = 4;
ints[1] = 5;
ints[2] = 6;
}

故事讲完了。 这里需要注意的是无论是传值还是传引用,传的都是复本(文档复印件或配的钥匙)。
[/Quote]

这个例子不错!
islandrabbit 2009-12-03
  • 打赏
  • 举报
回复
楼主这个问题不错啊!我想了一下,感觉还是用一个形象的故事来讲比较容易理解。

楼主这个问题可以归结为传值和传引用的区别问题。

下面开讲故事:

从前有个房间,房间里有份文档,房间还有一把钥匙。 这把钥匙在张三手里。

这时李四来向张三要那份文档。 张三不太喜欢李四,但又怕耽误了
工作不好交代。于是张三就把房间里文档的文档复印了一份,然后把那个复印件交给了李四(这叫传值)。

李四拿到文档后(复印件),胡乱修改一番,心想:张三,这回要你好看。可是他没想到那份原件还好好的在张三的房间里锁着呢。

以上故事对应:
public static void counter(int count) {
count = 2;
}

这个李四不甘心,于是他偷偷地配了一把张三的钥匙(这叫传引用), 准备进入房间修改那份文档。
这事被张三及时发现,他悄悄的把李四配的钥匙换成了另外一个房间的钥匙。
李四去了错误的房间。 张三再次以胜利告终!

以上故事对应:
public static void changeA1(int[] ints) {
int[] temp = new int[3];
ints = temp;

ints[0] = 7;
ints[1] = 8;
ints[2] = 9;
}

李四锲而不舍,他趁张三还沉浸两次胜利的喜悦里,终于成功的配了钥匙(这叫传引用),达到了修改那份文档原件的目的。
以上故事对应:
public static void changeA2(int[] ints) {
ints[0] = 4;
ints[1] = 5;
ints[2] = 6;
}

故事讲完了。 这里需要注意的是无论是传值还是传引用,传的都是复本(文档复印件或配的钥匙)。
xiaobluesky 2009-12-02
  • 打赏
  • 举报
回复
数组的传递肯定是引用传递!有点要说明,数组在第一次初始化之后,长度不可改变!changea1之所以使数组的改变的原因,是你新建了一个数组的引用temp,并且把新的数组引用赋给原来的引用ints!例:原来的ints指向的地址为123,而新tmp指向的地址是234,在赋值之后ints指向的地址234,所以在输出的时候输出的是234地址所指的那个数组!而真正原来地址123指向的数组并没发生改变!只是没有对象指向而已!
爱摸鱼de老邪 2009-12-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cangyingzhijia 的回复:]
引用 1 楼 still_rain 的回复:
因为Java是值传递。我的理解是,数组实际上传进去的是首地址的copy,2中改变了该copy的地址值,对原数组实际上没有做任何操作的。3中因为在copy中取了具体数组元素的地址,对该地址指向的数组元素值进行了操作,所以产生变化。对Java理解不够深刻,理解错误的话请见谅~~~~~

好好想想传值和引用的区别
[/Quote]
你没看懂的话就好好去翻翻书,别跟我扯传值和传引用的区别,这个我想还不用你来教我。
markshao 2009-12-01
  • 打赏
  • 举报
回复
数组应该是引用传递的
pasband 2009-12-01
  • 打赏
  • 举报
回复
public static void changeA1(int[] ints) {
int[] temp = { 4, 5, 6 };
ints = temp;
}


调用方法的时候相当于把原数组地址复制给ints了,
这里面new了一个数组,把新数组的地址给ints,
原数组没被改变。
jonay 2009-12-01
  • 打赏
  • 举报
回复
Java是参数全是值传递.
counter(count);相当于复制了一个count传进去,你改动的是复本,所以不影响方法外的值
changeA1(ints);这和上面的相似,不过传的是一个引用的复本,此方法里是把复本的引用转向引用其它地方了,没有改变方法外部的引用,也就是说方法里面的引用和外面的引用指向了不同的地址,
changeA2(ints);虽然传的是引用的复本,但指向的是同一个地址,你用方法里面的引用改动它所指向的值,当然会影响所以指向此地址的引用
唉,不知道说明白没,如果能画图就好了
苍蝇①号 2009-12-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 still_rain 的回复:]
因为Java是值传递。我的理解是,数组实际上传进去的是首地址的copy,2中改变了该copy的地址值,对原数组实际上没有做任何操作的。3中因为在copy中取了具体数组元素的地址,对该地址指向的数组元素值进行了操作,所以产生变化。对Java理解不够深刻,理解错误的话请见谅~~~~~
[/Quote]
好好想想传值和引用的区别
lovepay1413 2009-12-01
  • 打赏
  • 举报
回复
基本数据类型传递的是值,比如 int count = 1;counter(count);传进去的就是counter(1);
数组传递的是地址,也就是指针,传递了一个指向存放该数组地址的指针。
changeA1(ints);没有改变是因为你改变的不是那个地址里的东西。
changeA2(ints);你改变了存放这个数组的地址。
changeA1(ints);的操作你新生成了一个数组,然后将ints这个指针指向这个新数组temp的地址,外面调用方法前的ints指针还是指向原地址,所以没有变化。
changeA2(ints);直接使用原指针改变了原地址的值,所以改变了。
caili314 2009-12-01
  • 打赏
  • 举报
回复
调整数组大小、对数组赋值等操作实际上是产生了一个新的对象实例, 方法返回后在调用者处还是老的实例.
Jeff20040819 2009-12-01
  • 打赏
  • 举报
回复
UP
爱摸鱼de老邪 2009-12-01
  • 打赏
  • 举报
回复
因为Java是值传递。我的理解是,数组实际上传进去的是首地址的copy,2中改变了该copy的地址值,对原数组实际上没有做任何操作的。3中因为在copy中取了具体数组元素的地址,对该地址指向的数组元素值进行了操作,所以产生变化。对Java理解不够深刻,理解错误的话请见谅~~~~~

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧