java值传递问题

zfq642773391 2009-12-07 07:53:36
java中基本类型作参数传递时是值传递的,对象引用传递时也是值传递(拷贝引用的地址值)。可是有这么个问题不明白
上代码

public static void main(String args[]){
int a=1;
int b=2;
ValueSort vs=new ValueSort();
vs.swap(a, b);
System.out.println(a+" "+b);
}

public void swap(int m,int n){


int temp = m;

m = n;

n = temp;

}
由于是值传递,m、n是a、b的拷贝,在执行swap()时,只是形参m、n的值发生了变化,可是a和b的值并没有变
再看这个

public static void main(String[] args) {
// TODO Auto-generated method stub

int[] a={9,4,5,6,7,8,1};
InsertSort insort=new InsertSort();
insort.insertSort(a);
insort.print(a);
}

private void print(int[] a) {
// TODO Auto-generated method stub
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}

}

private void insertSort(int[] c) {
for(int p=1;p<c.length ;p++){
int tmp=c[p];
int j=p;
for( ;j>0 && (tmp<c[j-1]);j--){
c[j]=c[j-1];

}
c[j]=tmp;
}
}

这个排序算法,同样是值传递吧,数组c拷贝了a的值,经过排序,数组c被排序了,可是同时数组a也被排序了。
想不通这是为什么 ,请大家指教指教
...全文
424 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
至少空白很好 2011-06-01
  • 打赏
  • 举报
回复
一楼一语点醒梦中人啊
darxin 2009-12-10
  • 打赏
  • 举报
回复
楼主第二个例子改变的是数组对象的内容,所以改变的内容在函数调用之后会体现出来。

请参考另一组讨论
http://topic.csdn.net/u/20091209/16/b9cfb704-4eef-46a6-bdc3-552ee41e3036.html?62071
KingWolfOfSky 2009-12-10
  • 打赏
  • 举报
回复
一个是基本数据类型,一个是引用啊~~
楼主看看这个吧~~
http://blog.csdn.net/KingWolfOfSky/archive/2009/08/13/4444231.aspx
longtenggdf 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 wubill 的回复:]
引用 22 楼 longtenggdf 的回复:

虽然很形象,但是很遗憾,第一种说法是错误的。


我也是半路学java,给解释一下,第一种到底是怎么回事
[/Quote]
查了一下,你说的是正确的,是我理解出现了错误,基本类型只有引用(这里应该不叫引用了,因为它不引用任何对象),传递时确实是将引用复制一份。
longtenggdf 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 intel_vs_amd 的回复:]
引用 22 楼 longtenggdf 的回复:
引用 1 楼 wubill 的回复:
第一个简单类型值传递是直接复制简单类型值:
      你有两张纸(一张是a=1,另一张是b=2)
    swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
      自然和你原来的两张纸没什么关系

第二个复制的是指向数组的引用(并不是复制数组内的数据):
      好比你把你家的钥匙(相当于指向数组的引用a)复制了一把给inserSort
    inserSort用复制的钥匙打开了你家瞎折腾(这里就是排序)
      然后你用你自己的钥匙打开你家自然会看到别人折腾过了

虽然很形象,但是很遗憾,第一种说法是错误的。


为什么会是错误的呢?我想听听你的高见.....
[/Quote]
是在不好意思,我这里理解错了。我开始认为基本类型也是放在常量池中,以为基本类型也和对象类型一样,拥有引用-对象的结构。
后来查阅了质料才知道 基本类型只有引用。其实应该不叫引用,对象的引用里面放的是对象的内存地址,而基本类型里面放的就是值。
比如 int a = 1;在堆栈中就只有一个对象。

所以如果说

第一个简单类型值传递是直接复制简单类型值:
你有两张纸(一张是a=1,另一张是b=2)
swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
自然和你原来的两张纸没什么关系

也应该是正确的。虽然参数传递时复制了引用,但基本类型引用既是值,所以也是复制了基本类型的值。
我会一直关注这个贴子,之前发表了错误的言论,我很抱歉。
新建文件夹 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 longtenggdf 的回复:]
引用 1 楼 wubill 的回复:
第一个简单类型值传递是直接复制简单类型值:
      你有两张纸(一张是a=1,另一张是b=2)
    swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
      自然和你原来的两张纸没什么关系

第二个复制的是指向数组的引用(并不是复制数组内的数据):
      好比你把你家的钥匙(相当于指向数组的引用a)复制了一把给inserSort
    inserSort用复制的钥匙打开了你家瞎折腾(这里就是排序)
      然后你用你自己的钥匙打开你家自然会看到别人折腾过了

虽然很形象,但是很遗憾,第一种说法是错误的。
[/Quote]

为什么会是错误的呢?我想听听你的高见.....
ctlu2ct2t 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 longtenggdf 的回复:]
java只有值传递。
不同的结果是因为有可变与不可变的区别。int 不可变 所以 当你执行类似
int a = 1;
int b = a;
b = 10;时

因为1不可变,所以b只能指向一个新的10,而a还是指向了原来的1。(String 也是这样,他们都放在了常量池中以提高效率)
而数组时可变的。通过引用发生的操作都能改变本对象。
[/Quote]

学习!
longtenggdf 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wubill 的回复:]
第一个简单类型值传递是直接复制简单类型值:
      你有两张纸(一张是a=1,另一张是b=2)
    swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
      自然和你原来的两张纸没什么关系

第二个复制的是指向数组的引用(并不是复制数组内的数据):
      好比你把你家的钥匙(相当于指向数组的引用a)复制了一把给inserSort
    inserSort用复制的钥匙打开了你家瞎折腾(这里就是排序)
      然后你用你自己的钥匙打开你家自然会看到别人折腾过了
[/Quote]
虽然很形象,但是很遗憾,第一种说法是错误的。
longtenggdf 2009-12-09
  • 打赏
  • 举报
回复
JAVA编程思想上用遥控器和电视来解释这个问题。

引用就好比遥控器,对象好比电视。那么JAVA值传递的本质其实就是新买了一个遥控器而已。而不是新买一个电视。这样就很形象了,毕竟买一个遥控器要比买个电视开销小得多,可见其设计的合理性!

但是,这里有一个很关键的问题,有一些电视机是不能改变状态的(基本类型和放在常量池中的String),这里还想听起来有点别捏,不能改变那有没有遥控器都没有区别了。这里你就理解成时有线的遥控器吧,也就是遥控器的功能不光是来控制电视的状态,还指名了它到底连着哪个电视。

那你想换个台看电视怎么办呢??只好把遥控器从一个电视上拔下来,插到另一个电视上去了。这对原来的电视机以及插在它上面的其他遥控器都是毫无影响的!
longtenggdf 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 wubill 的回复:]
引用 22 楼 longtenggdf 的回复:

虽然很形象,但是很遗憾,第一种说法是错误的。


我也是半路学java,给解释一下,第一种到底是怎么回事
[/Quote]

JAVA参数传递只有一只形式,也就是我们都知道的值传递,不存在值的复制--其实我以前也认为是复制。复制的只有引用。
int a = 1;
int b = a;
b = 10;
最后打印出来a任然=1;这确实很容易让人觉得好像在 int b = a的时候,是将1复制了一份传给然后让b指向这个副本。其实不然,JVM对基本类型和String 的存储不一样,基本类型只储存在常量池中,常量池的内容在编译器确定,好比上面一断,
int a = 1; 编译器在编译到这里是就会往常量池中放入1;
b=10;会放入10;
常量池中的对象是不能改变的,所以它们叫常量。来看上面的代码到底做了什么事情。
int a = 1;在栈中创建一个引用a,指向在常量池中的1;
int b = a;在栈中创建一个引用b,它的值=引用a的值,也就是也指向了1.关键就在这里,1始终都只有一份,这样设计提高了JVM的效率。
b=10;引用b指向了常量池中的10;这个时候引用a任然指向了1.

三哥大大 2009-12-09
  • 打赏
  • 举报
回复
这个问题可以用内存分析来解释
1.a,b是两个局部变量,在栈中为它们分配内存空间 ,m,和n也是两个局部变量 也是在栈中为它们分配内存空间,它们的值分别是a,b的,要知道a和b的值也是在栈中的,不是在堆中分配的,而数组 名a也相当与一个局部变量,同理了,但数组的值是在堆中为其分配,然后把堆中的首地址赋给a,a在这里就相当与引用了
而现在a又传给了c,c也就引用了堆中的一块内存地址了,c在里面修改,那么a肯定也修改了


******
这样说明白吗

WuBill 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 longtenggdf 的回复:]

虽然很形象,但是很遗憾,第一种说法是错误的。
[/Quote]

我也是半路学java,给解释一下,第一种到底是怎么回事
loveliy520 2009-12-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wubill 的回复:]
第一个简单类型值传递是直接复制简单类型值:
      你有两张纸(一张是a=1,另一张是b=2)
    swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
      自然和你原来的两张纸没什么关系

第二个复制的是指向数组的引用(并不是复制数组内的数据):
      好比你把你家的钥匙(相当于指向数组的引用a)复制了一把给inserSort
    inserSort用复制的钥匙打开了你家瞎折腾(这里就是排序)
      然后你用你自己的钥匙打开你家自然会看到别人折腾过了
[/Quote]

这个比喻非常的形象,让人一看就会明白
方便面 2009-12-08
  • 打赏
  • 举报
回复
int 是简单类型,存放在栈里。
数组对象,放在堆里。
jjj3751386 2009-12-08
  • 打赏
  • 举报
回复
学习了,很经典
erzhikaoyu 2009-12-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wubill 的回复:]
第一个简单类型值传递是直接复制简单类型值:
      你有两张纸(一张是a=1,另一张是b=2)
    swap 相当于把两张纸用复印机各复印一张,然后把复印的换来换去
      自然和你原来的两张纸没什么关系

第二个复制的是指向数组的引用(并不是复制数组内的数据):
      好比你把你家的钥匙(相当于指向数组的引用a)复制了一把给inserSort
    inserSort用复制的钥匙打开了你家瞎折腾(这里就是排序)
      然后你用你自己的钥匙打开你家自然会看到别人折腾过了
[/Quote] 解释的很形象了 佩服
longtenggdf 2009-12-08
  • 打赏
  • 举报
回复
java只有值传递。
不同的结果是因为有可变与不可变的区别。int 不可变 所以 当你执行类似
int a = 1;
int b = a;
b = 10;时

因为1不可变,所以b只能指向一个新的10,而a还是指向了原来的1。(String 也是这样,他们都放在了常量池中以提高效率)
而数组时可变的。通过引用发生的操作都能改变本对象。
Akon90 2009-12-08
  • 打赏
  • 举报
回复
因为是引用的传递!
whut0802 2009-12-07
  • 打赏
  • 举报
回复
Integer的话,可以跟String比较一下
keeya0416 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zfq642773391 的回复:]
引用 9 楼 swandragon 的回复:
引用 3 楼 zfq642773391 的回复:
引用 2 楼 swandragon 的回复:
数组c拷贝了a的值,经过排序,数组c被排序了,可是同时数组a也被排序了

c和a是引用,指向同一块堆中的内容
c --> 9,4,5,6,7,8,1  <-- a
c --> 1,4,5,6,7,8,9  <-- a


那如果两个程序都不用基本类型int,而是对象,比如用Integer类,Integer数组a和c指向同一个内容,那对于第一个程序呢,Integer a=new Integer(1);Integer b=new Integer(2);这时,swap中的m、n应该传的是引用的地址,指向同一个对像,为什么还不能交换a、b的值呢?

Integer是final的

final类与普通类的使用几乎没有差别,只是它失去了被继承的特性,这与引用传递有什么关系呢?
[/Quote]
定义的方法参数是 int 的 这里的 integer 被传进去 进行了一个自动解箱的过程 也成了 int型的。
加载更多回复(13)

62,614

社区成员

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

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